Perl Weekly Challenge 105: singing roots

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 105.

PWC 105 - Task 1

The first task was about computing the nth root of a number. The script takes two integer arguments: the root level and the number of which I need to compute the root.
In Raku the task seems enough simple thanks to the .roots method that computes all the roots of a number. In particular, the one with no imaginary part (.roots computs Complex roots) is the one I am looking for. The script therefore reduces to a single line:

sub MAIN( Int $N = 5, Int $K = 248832 ) {
    "Computing $N root of $K".say;
    "%.2f".sprintf( .re ).say 
             for $K.roots( $N ).grep: { ! .im.Int };
}


That reads as:
  • for every .roots of level $N of the number $K;
  • search for (i.e., grep) every number that has the imaginery part .im zero;
  • produce a string with two decimals of the real .re part of such number;
  • print it with say.

I think this is a correct solution, even if it is not clear to me if there are other cases where this approach is not correct. Also note that I’m not aware of numbers that can have more than one real root, but to avoid problems I decided to substitute the for loop with a given that extracts the first one entry from the list:

sub MAIN( Int $N = 5, Int $K = 248832 ) {
    "Computing $N root of $K".say;
    "%.2f".sprintf( .re ).say 
             given $K.roots( $N ).grep( { ! .im.Int } )[ 0 ];
}


PWC 105 - Task 2

The second task was about the name game song: produce a stanza with a mangled person’s name. As far as I understand, the rules are to remove the initial letter from the name depending on its value.
What I did was to extract the $first-char of the name, and depending on it being a wovel or not, produce a $mangled-name that is the same name without its initial char or not. Then I produce an array of @special-chars that contain a single letter or an empty space depending again on the first char of the name.
Finally, I produce the stanza with an heredoc quoting composing the mangled name and the special char on every line they are required.

sub MAIN( Str $name = 'Katie' ) {
    my $first-char = $name.substr( 0, 1 ).lc;
    my $mangled-name = qw< a e i o u >.grep( * ~~ $first-char ) 
                         ?? $name 
                         !! $name.substr( 1, $name.chars ).lc;
    my @special-chars = qw< b f m >.map: 
                         { $_ !~~ $first-char ??  $_  !!  '' };

    say qq:to/SONG/;
    $name, $name bo-{ @special-chars[ 0 ] ~ $mangled-name.lc }
    Bonana-fanna fo-{ @special-chars[ 1 ] ~ $mangled-name.lc }
    Fee fi mo-{ @special-chars[ 2 ] ~  $mangled-name.lc }
    $name !
SONG
}



The article Perl Weekly Challenge 105: singing roots has been posted by Luca Ferrari on March 22, 2021