Let me demonstrate a few more solutions to some of the problems offered by the Perl Weekly Challenge site. This is what you can do during your breakfast.
Week 60, Task 2
From the given digits L, combine all possible numbers that are less than Y and that contain exactly X digits.
Here are the initial data for the task:
my @L = (0, 1, 2, 5); my $X = 2; my $Y = 21;
And here is the full solution:
(grep * < $Y, grep 10 < * < 100, [X~] @L xx $X).join(', ').say;
In this one-liner, we first generate $X
copies of the digits in @L
as @L xx $X
, then cross-concatenate them using [X~]
, then filter the numbers that have two digits (grep 10 < * < 100
) and finally only leave the numbers less than $Y
using another filter (grep * < $Y
).
The program prints the following list:
$ raku ch-2.raku 10, 11, 12, 15, 20
If we know that $Y
is less than 100, we can simplify the conditions, for example:
(grep 10 <= * < $Y, [X~] @L xx $X).join(', ').say;
Week 63, Task 1
Write a function that, from the given string, returns the last word that matches the given regex.
The task is accomplished with the example of code, which I converted to use Raku regexes here:
last_word(' hello world', /<[ea]>l/); # 'hello' last_word("Don't match too much, Chet!", rx:i/ch.t/); # 'Chet!' last_word("spaces in regexp won't match", /'in re'/); # undef last_word((1..1e6).join(' '), /^(3.*?) ** 3/); # '399933'
To find the words in the string and reverse them so that you can find the first instead of the last, you can use a couple of method calls: $str.words.reverse
. But, actually, you even don’t need that as the first
method accepts the :end
parameter, which makes first
to find the last occurrence (I hope it is optimised internally not to scan all items).
sub last_word($str, $re) { say $str.words.first: * ~~ $re, :end; }
And that’s the whole body of the function in question. Run the program and confirm it prints the words that were expected in the task:
$ raku ch-1.raku hello Chet! Nil 399933
→ GitHub repository
→ Navigation to the Raku challenges post series