use v6; # Problem 1 -- Find a way to express an integer as an expression containing four 9s # Since there's only 125 sequences of 9's with the basic arithmetic operators # and modulo between them, I generate all the sequences. If there were twelve # nines (about fify 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 $max = 81; my @operators = <+ - * / %>; my %operation = @operators Z=> (&infix:<+>, &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:(|([[@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"; }