Fooled by complexity
And that fool would be me. After realising that HyperSeq
is lazy, I managed to simplify the code in my last post.
sub needle(int \b) {
sub is-pentagon($c is raw) { (1+sqrt(1+24*$c))%%6 }
sub P($n is raw) { $n*(3*$n-1) div 2 }
loop (my int $s = 1; $s < b; $s++) {
my \bp = P(b);
my \sp = P($s);
if is-pentagon(bp + sp) && is-pentagon(bp - sp) {
return |(b, $s);
}
}
}
sub infix:<notnilor>(\maybenil, \alternative) {
maybenil =:= Nil ?? alternative !! maybenil
}
say (^∞).hyper(:batch(8), :degree(16)).map({.&needle notnilor Empty }).head;
The sub needle
transforms its argument or returns Nil
. By turning Nil
into Empty
, any call to .head
will skip all values that where not a hit. At least for strongly CPU-bound tasks, which allow for small batch sizes, .hyper
doesn’t overshoot much.
my atomicint $steps;
say (^∞).hyper(:batch(8), :degree(16)).map({$steps⚛++; .&needle notnilor Empty }).head;
say $steps;
# OUTPUT: (2167 1020)
2246
Right now, almost all task are CPU-bound. Once Rakudo has learned to produce better bytecode being able to stop sibling threads will become desirable.
UPDATE
lizmat suggested to simplify the code further by replacing .&needle notnilor Empty
with $_ with .&needle
. This works because when with
doesn’t fire, it returns Empty
. That I did not know. It is specced and also applies to if
. I filed the ENODOC under #4017. As it seems, we need to be careful not to run out of space on the interwebs by completing Raku’s docs.
-
January 17, 2022 at 13:552022.03 RakuCon How? – Rakudo Weekly News