Week 332 : 2025-07-28 (kind of)
Part 1
So it was the Perl and Rakue conference recently and there was an interesting talk I watched on Hyper operators by Bruce Grey. I must have had it in mind when I solved this weeks challenges. Or I'd been reading too much DC comics (if you know you know). Anyway lets take a look at the challanges.
For out first part we take a string that's a date and return the binary representation. That's simple enough, firstly lets define a type for "String in date format." we'll do it the easy way, pass it to the Date constructor and if that throws an exception it's not valid.
subset DateStr of Str where { my $r=False; try { Date.new($_); $r=True }; $r };
Note that I could also have done $_.Date
using casting to attempt to create my date. Also we're not catching
our exception just relying on it's existence to short circuit the try
block before $r
is set.
Then we'll make a test function we can run from the command line with our examples.
multi sub MAIN(:t(:$test)) is hidden-from-USAGE {
use Test;
is binary-date("2025-07-26"), "11111101001-111-11010";
is binary-date("2000-02-02"), "11111010000-10-10";
is binary-date("2024-12-31"), "11111101000-1100-11111";
}
And now to implement binary-date
which is easy enough. Break our string into a list of numbers (using comb
correctly as I learnt a few weeks ago), then we cast them to actual Ints
so
we can use the handy base
method to format them in a different base. Then just join this back up with a dash.
sub binary-date( DateStr $d ) {
$d.comb(/\d+/)>>.Int>>.base(2).join('-');
}
Normally I would use map
in this situation to do something to each element but as I say I was inspired so
pulled out the hyper operatores and it did great. Of course with a 3 element list you're not going to get any multi
threading benefits but it's still good practice.
Part 2
For this we want to return whether the counts of all the letters in the given string are odd. Which is simple enough,
split the string up (or comb it), drop the pieces in a Bag
get all the values from the Bag
and use the %%
divisible operator to see if they are divisible by 2. (Which you can do using hyper
operators, again.
As it's quite short I'll pop it below.
multi sub MAIN(:t(:$test)) is hidden-from-USAGE {
use Test;
ok !odd-letters("weekly");
ok odd-letters("perl");
ok !odd-letters("challenge");
done-testing;
}
sub odd-letters (Str $check) {
! any($check.comb.Bag.values >>%%>> 2)
}
#|( Given a string print whether each character in
it appears an odd number of times)
multi sub MAIN(Str $s) {say odd-letters($s)}
One thing with my process, solve the challenge monday morning while having coffee and blog about it Friday morning means
I will often come back to it and go "Why did I do that?". In this case why did I use ! any()
instead
of the simpler none
? To which I can only say, it was Monday morning and the coffee hadn't properly kicked
in.
Anyway, that was a fun little weeks challenge and I hope you've found my solutions interesting. Have fun.