Home > Raku > Fooled by complexity

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)

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.


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.

Categories: Raku
  1. No comments yet.
  1. January 17, 2022 at 13:55

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: