# t2/zbiciak

``````#!/usr/local/bin/perl6

# Find the first N numbers that are the sum of (at least) two distinct
# cubes with lazy evaluation.

sub sum_of_cube_finder
{
my (%sums, @pend, %pend);
my (Int \$n1, Int \$n1c, Int \$n2, Int \$sum);

\$n1 = 1;

return sub
{
while True {
\$n1++;
\$n1c = \$n1 ** 3;

# Return pending elements as long as \$n1 ** 3 is larger.
# This ensures we don't return a larger number ahead of
# a smaller number that might be found with the current \$n1.
@pend = %pend.keys.sort: { \$^a <=> \$^b };

while @pend.elems && \$n1c > @pend[0] {
\$sum = shift @pend;
%pend.delete(\$sum);
return \$sum, %sums{\$sum};
}

# Garbage collect any sums that will never be matched
# because \$n1 ** 3 got too big.
for %sums.keys { %sums.delete(\$_) if \$_ < \$n1c };

# Look for \$n1 ** 3 + \$n2 ** 3, for all \$n2 smaller than \$n1.
# If we detect a repeated sum, queue it up for later return.
for 1 ..^ \$n1 -> \$n2 {
\$sum = \$n1c + \$n2 ** 3;

%sums.push(\$sum => "\$n1 ** 3 + \$n2 ** 3");

%pend{\$sum} = 1 if (%sums{\$sum}.elems > 1);
}
}
}
}

sub MAIN(\$count)
{
my (Int \$sum, \$cubes);
my \$next_sum_of_cubes = sum_of_cube_finder;

for 1 .. \$count {
(\$sum, \$cubes) = \$next_sum_of_cubes();
say "\$sum = ", \$cubes.join(" = ");
}
}
``````

## Correctness

The first five lines of output are correct, then a large number of cubes are not found, starting with

``````39312 = 34 ** 3 + 2 ** 3 = 33 ** 3 + 15 ** 3
``````

The problem (or at least one problem) seems to be that `\$n1` is incremented at least once between finding two target numbers, so this algorithm cannot find two different target numbers that have the same `\$n1 ** 3` component.

## Consistency

The layout is a mixture of K&R and Allman style.

The vertical layout is a bit fragemented too, the inner loop in `sum_of_cube_finder` has more blank lines than the other loops, for no apparent reason.

## Clarity of intent

It is easy to follow the line of thought behind this solution, though the iterator-style control flow makes it unnecessarily hard to reason about the considered sums of cubes, and thus about correctness.

## Idiomatic use of Perl 6

Honorable use of list assignment (sometimes we forget our Perl 5 heritage), anonymous subs, `Hash.push` and `MAIN`.

A more seasoned Perl 6 programmer might have used `gather`/`take` and lazy lists instead of the custom iterator..

## Brevity

Doesn't go all out with brevity, but instead spaces itself out a bit. Still, not a lot of code for what it does.