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