Take a matrix and print its transposed version.
A matrix can be represented by nested arrays or lists. For example, here’s a square 2×2 matrix:
my @matrix = [1, 2],
[3, 4];
This is how the transposed matrix should look:
[[1, 3],
[2, 4]]
Actually, the outer pair of square brackets, could be added to the initializer of the @matrix variable. Perl 6 simply converts the list ([1, 2], [3, 4]) to an array when assigning it to an array variable @matrix.
Transposing a matrix is extremely easy:
my @transposed = [Z] @matrix;
The [Z] operator is a reduction form of the zip operator. For the given small matrix, it’s action is equivalent to the following code:
my @transposed = [1, 2] Z [3, 4];
Despite the simplicity of the method, it works well with bigger matrices as well as non-square ones.
For the example @matrix in this task, the output of the program is the following:
[(1 3) (2 4)]
For anyone finding this post in the future (it shows up in search engines to this day), please beware that using [Z] for transposing matrices fails when the input matrix has just one row:
> [Z] ((1,2,3),)
((1 2 3))
whereas the correct result would be ((1), (2), (3)).
There’s a section in the docs explaining why [Z] behaves this way (it’s because of the single-argument rule): https://docs.raku.org/language/traps#Using_%5B%E2%80%A6%5D_metaoperator_with_a_list_of_lists
Thus, it seems that in general one has to resort to a case differentiation:
given @matrix.elems { # or +@matrix to golf it
when 0 { () }
when 1 { @matrix[0].rotor(1) }
default { [Z] @matrix }
}
That’s because personally at least I’m not aware of any simpler idiom for transposition that works correctly in all cases. One might cook up something with slices, e.g. @matrix[*;0] and @matrix[*;1] and so on, but in my experiments this was three times slower. Also, if the transposition is just preparation for another operation, one might also concoct an ad-hoc fix for [Z] by adding two ineffectual rows before zipping: For example, to find the largest entry of each column of a 2-column matrix, one can do [Zmax] |@matrix, (0,0), (0,0) or better yet push the (0,0) somehow because slipping is slower. This guards against the cases of one or zero rows, but is not particularly nice.
Thus, I hope a proper transposition method gets introduced in the future — if it isn’t out there already.