Your praise is unjustified, however, because my solution is wrong. It doesn't find some valid results like (1 + 3)*(4 + 6) = 40 and others that can't be written without an initial parenthesis.
The correct solution (as I believe) I came up with this time around is comparatively boring. Essentially it builds all arithmetic expressions that can be built from the original numbers, eval's them and sees if they match the target.
In case anyone has picked up this ancient thread I'm appending it anyway.
Anno
sub solve { my ($target, @nums) = @_; return unless @nums; if ( @nums == 1 ) { return unless eval($nums[0]) eq $target; # eq for epsilon fuzz return @nums; } else { my @sol; for my $i ( 0 .. $#nums - 1 ) { for my $k ( $i + 1 .. $#nums ) { my @rem = @nums; my $nk = splice @rem, $k, 1; my $ni = splice @rem, $i, 1; for ( combine($ni, $nk) ) { unshift @rem, $_; push @sol, solve($target, @rem); shift @rem; } } } return @sol; } } sub combine { my ($x, $y) = @_; my ($vx, $vy) = map eval, $x, $y; my @combi = map operate($x, $y, $_), qw(+ *); push @combi, operate($x, $y, '-'); push @combi, operate($y, $x, '-') if $vx ne $vy; push @combi, operate($x, $y, '/') if $vy; push @combi, operate($y, $x, '/') if $vx and $vx ne $vy; @combi; } sub operate { my ($x, $y, $op) = @_; precedes($op, $_) and $_ = "($_)" for $x, $y; $op = " $op " if precedence($op) >= 3; "$x$op$y" } sub precedes { my ($op, $expr) = @_; precedence($op) < precedence($expr); } sub precedence { for ( shift ) { /\-/ and return 4; /\+/ and return 3; /\// and return 2; /\*/ and return 1; return 0; } } __END__
In reply to Re^3: Number from given digits puzzle
by Anno
in thread Number from given digits puzzle
by ambrus
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |