This is a solution to the Task 1 of the Perl Weekly Challenge Week 068.
You are given a matrix of size M x N
having only 0s
and 1s
. Write a script to set the entire row and column to 0
if an element is 0
.
The test input is here:
my @input = [1, 0, 1], [1, 1, 1], [1, 1, 1];
Let us solve the task somehow abstract.
We need to find all rows and all columns, where there is at least one zero. We need to fill all such rows and columns with zeros.
This is how you can find the indices of the rows which have at least one zero in it.
sub empty_lines(@data) { grep {!all(@data[$_])}, @data.keys; }
There is no difference between rows and columns if you think of them as of rows in a transposed matrix. That’s why I made the above filter a function. We can now call it twice: for the original data @input
it finds the rows, and for transposed variant [Z] @input
it finds the columns.
my @rows = empty_lines(@input); my @cols = empty_lines([Z] @input);
At this point you have the indices of both rows and columns, so just fill them with zeros.
for @rows X ^@input[0] -> ($row, $col) { @input[$row][$col] = 0; } for ^@input X @cols -> ($row, $col) { @input[$row][$col] = 0; }
We can merge the two loops into one:
for ((@rows X ^@input[0]), (^@input X @cols)).flat -> $row, $col { @input[$row][$col] = 0; }
Print the matrix and confirm it works with data of different sizes.
say @input.join("\n");
$ raku ch-1.raku 0 0 0 1 0 1 1 0 1
As a side note, an interesting fact about arrays in Raku. You can call the methods keys
and kv
on them. These methods are obvious for hashes, but for arrays, they return the indices of the elements in place of keys, so you can get pairs such as 0 => 1, 1 => 0, 2 => 1
for the first row of the source data in this task.
→ GitHub repository
→ Navigation to the Raku challenges post series