Download the raw code.

use v6;

sub gen_combine(@ops) {
    return -> Pair $x, Pair $y {
        $y.key == 0 ?? Nil !!
        @ops.map: {;.key.($x.key,$y.key) =>
             "($x.value() $_.value() $y.value())"};

my $c = gen_combine((&infix:<*> => "*",
                      &infix:</> => "/",
                      &infix:<%> => "%",
                      &infix:<+> => "+"));
sub infix:<c> {$c($^a,$^b)};

my @combinations := ({-9=>"(-9)",9=>"9"},{},{},{});
for 0..2 -> $n {
    for 0..$n -> $i {
        for (@combinations[$i] Xc @combinations[$n-$i]) -> $x {
                @combinations[$n+1]{$x.key} = $x.value;
sub MAIN(Int $n) {
    for (^($n+1)) Z @combinations[3]{^($n+1)} -> $v,$t {
        say $v ~ ($t[0].defined ?? " = $t[0]"!!"");


Produces the right output on Rakudo.


One loop body is indented two tabs relative to loop header, the rest is indented with single tabs. Otherwise it looks fine.

Clarity of intent

The program starts with a "seed" of 9 and -9, finds a way to combine smaller parts into larger parts, and prints the results.

Each part of the program builds on the one immediately previous. One has the sense that its author values making every word count.

It may help to read the Pair objects as actually being cons pairs, à la Lisp. That would make .key and .value mean car and cdr, respectively. We never go into any nesting of pairs, though, so no caddr, etc.

The array indices of @combinations are 1 index too low compared to what they "should" be. (I.e. @combinations[3] contains all expressions with 4 nines.) The onus of remembering this falls on the reader.

Algorithmic complexity

Fine. It's fast. The fastest Rakudo-based solution, in fact.

Idiomatic use of Perl 6

Declaring an infix op so that you can use the cross meta operator on it? That is quite possible the Perl 6-est thing anyone has ever done in this context to date. (And it makes sense to do it, mind.)

Also nice use of the method-related string interpolation rules.


This code doesn't shed words to arrive at a solution.