Download the raw code.
#!/usr/bin/env perl6
# This is perl6 version 2011.12-18-ga7fd89e built on parrot 3.11.0 revision RELEASE_3_11_0
sub parens( $s ) {
return $s eq '9' ?? $s !! '(' ~ $s ~ ')';
};
sub operate( $num1, $exp1, $num2, $exp2 ) {
my @result;
push @result, $num1 + $num2;
push @result, parens( $exp1 ) ~ " + " ~ parens( $exp2 );
push @result, $num1 - $num2;
push @result, parens( $exp1 ) ~ " - " ~ parens( $exp2 );
push @result, $num1 * $num2;
push @result, parens( $exp1 ) ~ " * " ~ parens( $exp2 );
if $num2 != 0 {
push @result, $num1.Int div $num2.Int;
push @result, parens( $exp1 ) ~ " / " ~ parens( $exp2 );
push @result, $num1 % $num2;
push @result, parens( $exp1 ) ~ " % " ~ parens( $exp2 );
};
return @result;
}
sub mate-levels( %numexp1, %numexp2 ) {
my @result;
for %numexp1.kv -> $num1, $exp1 {
for %numexp2.kv -> $num2, $exp2 {
push @result, operate $num1, $exp1, $num2, $exp2;
push @result, operate $num2, $exp2, $num1, $exp1;
}
}
return @result;
}
sub insert-num-exp-pairs( %dst, @new ) {
for @new -> $num, $exp {
# Select the most readable (=shortest) expression.
if not %dst.exists( $num ) or %dst{$num}.chars > $exp.chars {
%dst{$num} = $exp;
}
}
}
sub MAIN ( Int $N ) {
# @all[1] holds numbers and expressions built with 1 nine.
# @all[2..4] will hold numbers and expressions built with 2..4 nines.
#
# There are very few of those (<40) at @all[4] so one could just as
# well predeclare value => expression hash with all the entries.
my @all = (
{},
{ 9 => "9", -9 => "-9" },
{},
{},
{}
);
insert-num-exp-pairs( @all[2], mate-levels( @all[1], @all[1] ));
insert-num-exp-pairs( @all[3], mate-levels( @all[1], @all[2] ));
insert-num-exp-pairs( @all[4], mate-levels( @all[1], @all[3] ));
insert-num-exp-pairs( @all[4], mate-levels( @all[2], @all[2] ));
for 0 .. $N -> $n {
say $n ~ ( @all[4].exists( $n ) ?? ' = ' ~ @all[4]{$n} !! '' );
};
}
The only significant change to the previous version seems to be this:
@@ -17,12 +19,12 @@
push @result, parens( $exp1 ) ~ " * " ~ parens( $exp2 );
if $num2 != 0 {
- push @result, $num1 / $num2;
+ push @result, $num1.Int div $num2.Int;
push @result, parens( $exp1 ) ~ " / " ~ parens( $exp2 );
Which unfortunately leads to incorrect output. It now produces
4 = 9 / ((9 + 9) / 9)
Where the right-hand side produces 4.5 in proper arithemtic, not 4.