Perl Weekly Challenge: Week 105
Challenge 1:
Nth Root
You are given positive numbers
$N
and$k
.Write a script to find out the
$Nth
root of$k
. For more information, please take a look at the wiki page.
Example
Input: $N = 5, $k = 248832
Output: 12
Input: $N = 5, $k = 34
Output: 2.02
For once a math problem I actually knew how to do. Here's my Raku solution.
sub MAIN(
Int $N, #= root
Int $k #= number
) {
say ($k ** (1.0 / $N)).round(0.01);
}
Originally, I didn't have the call to .round()
at the end and as a result for the first example I actually got
12.000000000000002
, an unfortunate side effect of the inability of binary computers to represent decimal arithmetic. And for the second example I got 2.024397458499885
. That's why I decided to round to 2 decimal places.
Perl doesn't have a builtin round function in its' library (though it gives the proper answer for the first example anyway.) so I had to use the Math::Round
module. This is the relevant code.
say nearest(0.01, $k ** (1.0 / $N));
As you can see, the actual function I used was nearest()
not round()
which only works on integers.
Challenge 2:
The Name Game
You are given a
$name
.Write a script to display the lyrics to the Shirley Ellis song
The Name Game
. Please checkout the wiki page for more information.
Example
Input: $name = "Katie"
Output:
Katie, Katie, bo-batie,
Bonana-fanna fo-fatie
Fee fi mo-matie
Katie!
This was a fun one.
sub MAIN(
Str $name,
) {
my $stem = $name.subst(/^ <-[AaEeIiOoUu]> /, q{}).lc;
The first step is to strip off the first consonant from the $name
. For good measure
the resulting $stem
is converted to lower case.
my Bool $labial = $name.match(/^ <[BbFfMm]> /).Bool;
say "$name, $name, bo-", $labial ?? q{} !! 'b', "$stem";
say "Bonana-fana fo-", $labial ?? q{} !! 'f', "$stem";
say "Fee fi mo-", $labial ?? q{} !! 'm', "$stem";
say "$name!";
Now we just print the verse adding what linguists call labial sounds onto $stem
to make a rhyme for the $name
.
There is an exception though. If the $name
begins with b, f, or m, the labial is not added. So before printing
the verse we check for an initial b, f, or m and assign a boolean to indicate whether we have it or not. And we use
it to control the printing.
}
The perl version is slightly more verbose but works the same way.
my ($name) = @ARGV;
my $stem = $name;
$stem =~ s/^ [^AaEeIiOoUu] //msx;
$stem = lc $stem;
my $labial = $name =~ / ^ ([BbFfMm]) /msx;
say "$name, $name, bo-", ($labial ? q{} : 'b'), "$stem";
say "Bonana-fana fo-", ($labial ? q{} : 'f'), "$stem";
say "Fee fi mo-", ($labial ? q{} : 'm'), "$stem";
say "$name!";