# t1/timtom

``````use v6;

# Problem 1 -- Find a way to express an integer as an expression containing four 9s
# Since there's only 64 sequences of 9's with the basic arithmetic operators
# between them, I generate all the sequences.  If there were twelve nines (about
# four million permutations), I might think about using a different approach.

die "Maximum index argument required." unless @*ARGS;
my \$max = @*ARGS[0].Int;
die "Maximum index argument must be an integer" if \$max ne @*ARGS[0];

my @operators = <+ - * />;
my %operation = @operators Z=> (&infix:<+>, &infix:<->, &infix:<*>, &infix:</>);

# Skip some of the equivalent expressions. There are more, but these are the
# only set of length two, which are going to have the most impact.
my \$skip = any(<-+ /*>);

my %valid;

# List auto-flattening makes this more verbose than it should need to be.  While
# I don't think that it's neccessarily a bug, it would be nice to have some way
# to have the for loop not auto-flatten my cross operation.
my \$cross := infix:<X>(|([[@operators]] xx 3));
for ^\$cross.elems -> \$index
{
my @ops_str = @(\$cross[\$index]);
next if any(@ops_str Z~ @ops_str[1 .. *]) ~~ \$skip;
my @ops = %operation{@ops_str};
my \$result = (9, @ops).reduce: -> \$so-far, \$op { \$op(\$so-far,9) };
next unless \$result == \$result.Int && \$result > 0 && \$result <= \$max;
# RAKUDOBUG: Hash.push was flattening my list no matter how many sets
# of square brackets I put there.
%valid{\$result} = [] unless %valid.exists(\$result);
my \$value = [@ops_str];
%valid{\$result} = [@(%valid{\$result}), \$value];
}

for 1 .. \$max -> \$num
{
print \$num;
if %valid.exists: \$num
{
print ":";
my \$first = True;
for @(%valid{\$num}) -> \$expr
{
print " OR" if !\$first;
\$first = False;
print ' ' ~ ((9 xx \$expr.elems Z \$expr), 9);
}
}
print "\n";
}
``````

## Correctness

A brief excerpt from the output demonstrates the problem:

``````3: 9 + 9 + 9 / 9
``````

No parenthesis, expressions are always evaluated from left to right. That is not only a problem of the output routine, but a deeper one. Without using parentheses, you cannot express `324 = (9 + 9) * (9 + 9)` because it doesn't evaluate from left to right. Also, the program starts with printing the 1, ignoring the 0. In total it produces only 20 of the 29 numbers between 0 and 1000.

## Clarity of intent

The code is dense, but not hard to follow.

## Algorithmic efficiency

Reasonable. It is one of the faster solutions, at the price of not finding all expressions. As MJD says, "It's easy to get the wrong answer in O(1)".

## Idiomatic use of Perl 6

There's much to like: the use of hash slicing, the `X` and `Z` operators and meta operators, `.reduce`, and the reasonable use of junctions. If you know that `\$expr` holds the operators,

``````print ' ' ~ ((9 xx \$expr.elems Z \$expr), 9);
``````

is cute.

Some lines could have been a bit more idiomatic, for example the unwieldly

``````%valid{\$result} = [] unless %valid.exists(\$result);
``````

Could have been shortened to

``````%valid{\$result} //= [];
``````

Some lines were wasted on validating command-line arguments, which could've been more idiomatically done with `MAIN`.

## Brevity

Oh yes. Ignoring comments and blank lines, there are 8 lines declarations and initialization, 12 lines of generating the expresions, and another 16 for printing. But then it does less than other solutions, and too little at that.