Download the raw code.
use v6;
sub merge(@cc) {
gather {
my @a := @cc.shift;
take @a.shift;
my @b := merge(@cc);
loop {
@a[0].key == @b[0].key and @b[0].value.push(@a.shift.value[]);
take @a[0].key < @b[0].key ?? @a.shift !! @b.shift;
}
}
}
sub MAIN(Int $count) {
#build matrix of cubic sums with their string representation
my @csums := (1..*).map: -> $o {$(($o..*).map: {
($_**3+$o**3 => ["$_ ** 3 + $o ** 3"]) }) };
#merge the matrix into a sorted list and filter out only the multiple hits
my @results := merge(@csums).grep:{.value.elems > 1};
#make pretty strings out of the results
my @pretty := @results.map({"$_.key() = " ~ .value.join(" = ")});
#print the results. This is where all the work is done.
@pretty.shift.say for ^$count;
}
This code finds all sums of cubes.
It also seems to handle the case of more than two ways to write a sum of cubes, though excessive resource usage prevented us from testing it.
Tabs and spaces are used more or less interchangeably, without any fixed
rule, and assuming a tabstop
of 4.
Again each part builds on the previous one. First a stream merge is defined, then filled with a lazy, two-dimensional list of sums of cubes, then filtered for non-unique elements and finally pretty-printed.
Straightforward, if you are used to thinking in such patterns.
This is a relatively slow solution, since it enqueues all sums of cubes, instead of pre-filtering with a hash and then enqueuing only the duplicates, as the faster solutions do.
Nice use of infinite, lazy streams, gather
/take
and binding to make sure
everything stays lazy.
Slimmed. Not an ounce of fat.