# -*- mode: cperl6; -*- # 2011 Perl 6 Coding Contest # Edgar Gonzàlez i Pellicer use v6; # A term class Term { has $.value; has $.expression; } # Sum two terms sub sum-terms(Term $t1, Term $t2) { # Include lowest term first in the expression my $expr = $t1.value < $t2.value ?? sprintf('%s + %s', $t1.expression, $t2.expression) !! sprintf('%s + %s', $t2.expression, $t1.expression); # Return the sum return Term.new(value => $t1.value + $t2.value, expression => $expr); } # Merge two streams sub merge($s1, $s2) { return gather { # Clone the streams my $ws1 = $s1.clone; my $ws2 = $s2.clone; # While both remain while $ws1 && $ws2 { # Compare heads, and advance the lowest if $ws1[0].value < $ws2[0].value { take $ws1.shift(); } else { take $ws2.shift(); } } # Finish streams take $ws1.shift() while $ws1; take $ws2.shift() while $ws2; } } # Merge the sums of two streams sub merge-sums($s1, $s2) { return gather { # Clone the streams my $ws1 = $s1.clone; my $ws2 = $s2.clone; # While both remain while $ws1 && $ws2 { # Take heads my $h1 = $ws1.shift(); my $h2 = $ws2.shift(); # Sum of heads take sum-terms($h1, $h2); # Rest of merge-sums take $_ for merge(merge($ws2.map({ sum-terms($h1, $_) }), $ws1.map({ sum-terms($_, $h2) })), merge-sums($ws1, $ws2)); } } } # Main multi sub MAIN(Str $n-str) { # Cubes my $cubes = (1 .. *).map({ Term.new(value => $_ ** 3, expression => sprintf("%d ** 3", $_)) }); # Merge them my $merged = merge-sums($cubes, $cubes); # How many my $n = $n-str.Int; # Iterate my $prev = $merged.shift(); while $n > 0 && $merged { # Store the first my @terms = $prev; # Next my $next = $merged.shift(); while $next.value == $prev.value { # Different expression? @terms.push($next) if $next.expression ne $prev.expression; # Next $prev = $next; $next = shift($merged); } # How many? if @terms > 1 { say(($prev.value, @terms>>.expression).join(' = ')); --$n; } # Last $prev = $next; } } # Call main MAIN(|@*ARGS);