Algorithm::Loops generates all the permutation of operators needed and then the numbers are zipped forming a single string. This is the point where eval $string would produce the same results as your code. Instead, I break each term apart and keep a running total of the value which is returned.
In my opinion, what would make the puzzle much more interesting would be to require single expression evaluation as your solution does but prohibit the use of eval $string. Here is my original solution modified accordingly though it is quite slow and a bit obfu now. Thanks for the puzzle.
#!/usr/bin/perl use strict; use warnings; use Algorithm::Loops qw{NestedLoops MapCar}; my $year = $ARGV[0] || 2006; my @digit = reverse 1..9; my $next = NestedLoops( [ ['+', '-'], ([qw{+ - / *}, '']) x $#digit ] +); while ( my @perm = $next->() ) { my @expr = split m|([/*+-])|, join '', MapCar { @_ } \@perm, \@dig +it; print "@expr\n" if evaluate(@expr) == $year; } sub evaluate { my @expr = @_; splice @expr, 0, 3, $expr[2] * ($expr[1] eq '-' ? -1 : 1); for (1 .. 2) { my $op = $_ % 2 ? qr|([*/])| : qr|([+-])|; for (my $i = 1; $i < $#expr;) { my ($x, $y) = ($expr[$i - 1], $expr[$i + 1]); if ($expr[$i] =~ /$op/) { my $val = $1 eq '*' ? $x * $y : $1 eq '/' ? $x / $y : +$1 eq '+' ? $x + $y : $x - $y; splice @expr, $i - 1, 3, $val; } else {$i += 2} } } return $expr[0]; }
Cheers - L~R
In reply to Re^3: Happy 2006
by Limbic~Region
in thread Happy 2006
by Perl Mouse
For: | Use: | ||
& | & | ||
< | < | ||
> | > | ||
[ | [ | ||
] | ] |