Perl Weekly Challenge 45: encoded messages and self-source-code-printing

One way to let me improve my knowledge about Raku (aka Perl 6) is to implement programs in it. Unluckily, I don’t have any production code to implement in Raku yet (sob!). So, why not try solving the Perl Weekly Challenge tasks?

In the following, the assigned tasks for Challenge 45.
My official solutions are available on the GitHub repository.

PWC 45 - Task 1

The task asks to get a message, remove all the spaces and distribute the message across an eight column matrix. Finally, print the message by columns instead of rows. This is called the squate secret code.
To better understand, let’s consider the following example:
% perl6 ch-1.p6 --message="The quick brown fox jumps over the lazy dog"
Your original message is
The quick brown fox jumps over the lazy dog
and encoded results:

  t h e q u i c k
  b r o w n f o x
  j u m p s o v e
  r t h e l a z y
  d o g

  that leads to

 tbjrdhrutoeomhgqwpeunslifoacovzkxey

First of all, I need to get a matrix with all non spaces chars:
for $message.lc.comb( / \w / )  {
    @matrix[ $row ].push: $_ if @matrix[ $row ].elems < $columns;
    $row++ if @matrix[ $row ].elems == $columns;
}
The comb method extracts only the letters (non-spaces) from the string $message, then I push every single letter into @matrix[ $row ], that is an array of array (indexed by $row) up until $columns (i.e., 8 columns). Once I hit the $columns (i.e., 8) upper limit, I change the matrix row.
Now it’s time to print the matrix by columns:
for 0 .. $columns -> $start {
    ( @matrix[ $_ ][ $start ] // '' ).print for 0 .. $row;
}
I loop over the $columns first, and then I do print the current position between all the matrix rows (i.e., between 0 .. $row, with the latter being increased by the preceeding loop). Please note that the matrix could have the last line not completed, so I print a char or an empty char if nothing is defined in that matrix position.

A Smaller Solution

I was not satisfied about the above solution, and after a while I remembered that strange method that I seldom use: rotor. This method splits a list into sublists of the specified size, and with the :partial adverb, can include also lists that are not complete. Therefore, the whole first loop can be reduced to:
my @matrix = $message
               .lc
               .comb( /\w/ )
               .rotor: 8, :partial;
that produces the very same @matrix as the loop before, and moreover, the @matrix.elems corresponds to the number of rows the matrix has. From the above, the printing loop becomes:
for 0 .. $columns -> $start {
    ( @matrix[ $_ ][ $start ] // '' ).print for 0 .. @matrix.elems;
}

PWC 45 - Task 2

This has been very easy, a single line script: provide a program that prints its own source code. Since in Raku, the dynamic variable $*PROGRAM olds an IO object, I can simply loop over the lines and print them out.
  .say for $*PROGRAM.lines;
Either this has been too simple, or I didn’t understand the task assignment!

The article Perl Weekly Challenge 45: encoded messages and self-source-code-printing has been posted by Luca Ferrari on January 29, 2020