#!/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(" = "); } }