## Perl Weekly Challenge 242: Flip Matrix

These are some answers to the Week 242, Task 2, 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 November 12, 2023, at 23:59). This blog post offers some solutions to this challenge. Please don’t read on if you intend to complete the challenge on your own.

You are given `n x n` binary matrix.

Write a script to flip the given matrix as below.

``````1 1 0
0 1 1
0 0 1

a) Reverse each row

0 1 1
1 1 0
1 0 0

b) Invert each member

1 0 0
0 0 1
0 1 1
``````

Example 1

``````Input: @matrix = ([1, 1, 0], [1, 0, 1], [0, 0, 0])
Output: ([1, 0, 0], [0, 1, 0], [1, 1, 1])
``````

Example 2

``````Input: @matrix = ([1, 1, 0, 0], [1, 0, 0, 1], [0, 1, 1, 1], [1, 0, 1, 0])
Output: ([1, 1, 0, 0], [0, 1, 1, 0], [0, 0, 0, 1], [1, 0, 1, 0])
``````

### Flip Matrix in Raku

The `flip-matrix` subroutine simply traverses the rows of the input matrix, reverses them and inverts each item of the row. It could easily be done in a single code line, but we kept two lines to better express the two steps of the process.

``````sub flip-matrix (@input) {
my @in = @input;
my @out;
for @in -> @row {
my @rev = @row.reverse;
push @out, map { \$_ eq '0' ?? 1 !! 0 }, @rev;
}
return @out;
}
for (<1 1 0>, <0 1 1>, <0 0 1>),
(<1 1 0>, <1 0 1>, <0 0 0>),
(<1 1 0 0>, <1 0 0 1>, <0 1 1 1>, <1 0 1 0>)
-> @test {
say @test, " => ", flip-matrix @test;
}
``````

This program displays the following output:

``````\$ raku ./flip-matrix.raku
((1 1 0) (0 1 1) (0 0 1)) => [(1 0 0) (0 0 1) (0 1 1)]
((1 1 0) (1 0 1) (0 0 0)) => [(1 0 0) (0 1 0) (1 1 1)]
((1 1 0 0) (1 0 0 1) (0 1 1 1) (1 0 1 0)) => [(1 1 0 0) (0 1 1 0)
(0 0 0 1) (1 0 1 0)]
``````

### Flip Matrix in Perl

This is a port to Perl of the above Raku program. Again, the `flip_matrix` subroutine traverses the rows of the input matrix, reverses them and inverts each item of the row. It is slightly more complicated than the Raku version because it is a bit of a pain in the neck to display properly references to nested arrays. This is the reason for which we added a helper subroutine, `stringify_matrix`, to display both the input and the output matrices.

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

sub stringify_matrix {
my @in = @_;
my \$out = "";
\$out .=  "(@\$_) " for @in;
return \$out;
}

sub flip_matrix {
my @in = @_;
my @out;
for my \$row (@in) {
my @rev = reverse @\$row;
push @out, [map { \$_ eq '0' ? 1 : 0 } @rev];
}
return @out;
}
for my \$test ([[<1 1 0>], [<0 1 1>], [<0 0 1>]],
[[<1 1 0>], [<1 0 1>], [<0 0 0>]],
[[<1 1 0 0>], [<1 0 0 1>], [<0 1 1 1>], [<1 0 1 0>]]) {
print stringify_matrix @\$test;
say " => ", stringify_matrix flip_matrix @\$test;
}
``````

This program displays the following output:

``````\$ perl ./flip-matrix.pl
(1 1 0) (0 1 1) (0 0 1)  => (1 0 0) (0 0 1) (0 1 1)
(1 1 0) (1 0 1) (0 0 0)  => (1 0 0) (0 1 0) (1 1 1)
(1 1 0 0) (1 0 0 1) (0 1 1 1) (1 0 1 0)  => (1 1 0 0) (0 1 1 0)
(0 0 0 1) (1 0 1 0)
``````

## 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 November 19, 2023. And, please, also spread the word about the Perl Weekly Challenge if you can.