# Perl Weekly Challenge 270: Special Positions

These are some answers to the Week 270, Task 1, of the Perl Weekly Challenge organized by Mohammad S. Anwar.

Spoiler Alert: This weekly challenge deadline is due in a few days from now (on May 26, 2024 at 23:59). This blog post provides some solutions to this challenge. Please don’t read on if you intend to complete the challenge on your own.

Task 1: Special Positions

You are given a m x n binary matrix.

Write a script to return the number of special positions in the given binary matrix.

A position (i, j) is called special if $matrix[i][j] == 1 and all other elements in the row i and column j are 0.

Example 1

Input: $matrix = [ [1, 0, 0],
                   [0, 0, 1],
                   [1, 0, 0],
                 ]
Output: 1

There is only one special position (1, 2) as $matrix[1][2] == 1
and all other elements in row 1 and column 2 are 0.

Example 2

Input: $matrix = [ [1, 0, 0],
                   [0, 1, 0],
                   [0, 0, 1],
                 ]
Output: 3

Special positions are (0,0), (1, 1) and (2,2).

Special Positions in Raku

We use an array slice (with the any junction) to check rows and standard for loop to check columns.

sub special-positions (@mat) {
    my $row-max = @mat[0].end;
    my $count = 0;
    IND_I: for 0..$row-max -> $i {
        for 0..@mat.end -> $j {                            `
            next if @mat[$i][$j] != 1;
            next unless 
                (@mat[$i][0..^$j, $j^..$row-max]).any != 0;
            for 0..@mat.end -> $k {
                next if $k == $i;
                next IND_I unless @mat[$i][$k] == 0;
            }
            # say "$i, $j"; # uncomment to see the positions
            $count++;
        }
    }
    return $count;
}

my @tests = 
        [ [1, 0, 0],
          [0, 0, 1],
          [1, 0, 0],
        ],
        [ [1, 0, 0],
          [0, 1, 0],
          [0, 0, 1],
        ];
for @tests -> @test {
    printf "%-8s %-8s ... => ", "@test[0]", "@test[1]";
    say special-positions @test;
}

This program displays the following output:

$ raku ./special-positions.raku
1 0 0    0 0 1    ... => 1
1 0 0    0 1 0    ... => 3

Special Positions in Perl

This is a port to Perl of the above Raku program. Since Perl doesn't have any junction, we had to replace it with a for loop.

use strict;
use warnings;
use feature 'say';

sub special_positions {
    my $mat = shift;
    my $row_max = $#{$mat->[0]};
    my $col_max =  $#{$mat};
    my $count = 0;
    for my $i (0..$row_max) {
    IND_J: for my $j (0..$col_max) {
            next if $mat->[$i][$j] != 1;
            # check row
            for my $m (0..$row_max) {
                next if $m == $i;
                next IND_J unless $mat->[$m][$j] == 0;
            }
            # check column
            for my $k (0..$col_max) {
                next if $k == $j;
                next IND_J unless $mat->[$i][$k] == 0;
            }
            # say "$i, $j"; # uncomment to see the positions
            $count++;
        }
    }
    return $count;
}

my @tests = (
        [ [1, 0, 0],
          [0, 0, 1],
          [1, 0, 0],
        ],
        [ [1, 0, 0],
          [0, 1, 0],
          [0, 0, 1],
        ]
        );
for my $test (@tests) {
    printf "[%-8s %-8s ...] => ", "@{$test->[0]}", "@{$test->[1]}";
    say special_positions $test;
}

his program displays the following output:

$ perl ./special-positions.pl
[1 0 0    0 0 1    ...] => 1
[1 0 0    0 1 0    ...] => 3

Wrapping up

The next week Perl Weekly Challenge will start soon. If you want to participate in this challenge, please check https://perlweeklychallenge.org/ and make sure you answer the challenge before 23:59 BST (British summer time) on June 2, 2024. And, please, also spread the word about the Perl Weekly Challenge if you can.

Leave a comment

About laurent_r

user-pic I am the author of the "Think Perl 6" book (O'Reilly, 2017) and I blog about the Perl 5 and Raku programming languages.