Flipping members
Weekly challenge 242 — 6 November 2023
Week 242  6 Nov 2023
You are given n x n binary matrix. Write a script to flip the given matrix as follows:
Given:
1 1 0
0 1 1
0 0 1
0 1 1
1 1 0
1 0 0
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])
This is a task that requires a bit of thought and then not much code. My solution
involves references to arrays of references, which allows a very concise solution
but maybe not the most readable one. For someone unfamiliar with Perl a statement
such as @row = @{$_[$j]};
may be rather impenetrable, though all it's
doing is assigning the jth row of the input matrix to the array @row

and by the way that's the jth row counting from zero.
For production code which might have to be maintained by someone else I'd probably expand that into several lines unless performance were an issue  which with today's computers it rarely is.
The essence of my solution is this line of code:
$flipped[$j][$_] = 1  $row[$n  $_] for (0 .. $n);
The use of $n  $_
reverses the order, and the 1 
flips the bits,
but again that's not terribly obvious: for example, realising that $_ is the iterating
variable in the for loop, and that the left hand side of the assignment is simply an element
of a 2dimensional array.
It's also interesting that printing out the matrix takes almost as much code as creating it, and again the code is probably rather opaque for a Perl newbie.
#!/usr/bin/perl use v5.16; # The Weekly Challenge  20231106 use utf8; # Week 242 task 2  Flip matrix use strict; # Peter Campbell Smith use warnings; # Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge flip_matrix([1, 1, 0], [0, 1, 1], [0, 0, 1]); flip_matrix([1, 1, 0, 0], [1, 0, 0, 1], [0, 1, 1, 1], [1, 0, 1, 0]); flip_matrix([1, 0, 0, 0, 0], [0, 1, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 0, 1, 0], [0, 0, 0, 0, 1]); sub flip_matrix { my ($n, $j, @row, @flipped); # reverse and flip $n = @{$_[0]}  1; for $j (0 .. $n) { @row = @{$_[$j]}; $flipped[$j][$_] = 1  $row[$n  $_] for (0 .. $n); } # show input and output print_matrix(qq(\nInput: [), \@_); print_matrix(qq(\nOutput: [), \@flipped) } sub print_matrix { my ($legend, $matrix, $j); # format rows of matrix ($legend, $matrix) = @_; for $j (0 .. @$matrix  1) { say qq[$legend] . join(', ', @{$matrix>[$j]}) . qq(]); $legend = ' ['; } }
Input: [1, 1, 0] [0, 1, 1] [0, 0, 1] Output: [1, 0, 0] [0, 0, 1] [0, 1, 1] Input: [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] Input: [1, 0, 0, 0, 0] [0, 1, 0, 0, 0] [0, 0, 1, 0, 0] [0, 0, 0, 1, 0] [0, 0, 0, 0, 1] Output: [1, 1, 1, 1, 0] [1, 1, 1, 0, 1] [1, 1, 0, 1, 1] [1, 0, 1, 1, 1] [0, 1, 1, 1, 1]