use v6; =begin pod A solution to problem 2 of the Perl 6 2011 Coding Contest http://strangelyconsistent.org/blog/the-2011-perl-6-coding-contest by Ian Fraser, 2012-01-29 Finds the first N numbers that can be expressed as a sum of two cubes in more than one way =end pod sub solve_for(Int \$n) { my %sum_one_way; my %candidates; my \$max_of_first_n = 0; # We need to find the smallest \$n solutions. # Although there may be some candidates smaller than the first \$n we find # we don't need any that are larger than the mmaximum of the first \$n. my \$i = 1; repeat until (%candidates.elems >= \$n && \$i ** 3 >= \$max_of_first_n) { for (1 .. \$i) -> \$j { # we're computing cubes more often than we need to here # but indexing into a lazily computed list of cubes was slower my \$sum = \$j ** 3 + \$i ** 3; my \$formula = "\$j ** 3 + \$i ** 3"; if ! %sum_one_way.exists(\$sum) { %sum_one_way{\$sum} = \$formula; } else { %candidates{\$sum} = [ %sum_one_way{\$sum} ] unless %candidates.exists(\$sum); %candidates{\$sum}.push(\$formula); \$max_of_first_n max= \$sum if %candidates.elems <= \$n; } } \$i++; } my @in_order = %candidates.pairs.sort( { +.key } ); for @in_order[ 0 .. \$n - 1 ] -> \$p { say join(" = ", \$p.key, \$p.value.list); } } multi MAIN(Int \$n) { return unless \$n > 0; solve_for(\$n); }