本帖最后由 523066680 于 2019-4-15 21:20 编辑
| use Math::BigRat; | | STDOUT->autoflush(1); | | our %hash; | | our @op = qw/+ - * \//; | | my $num = "5551"; | | my @nums= split("", $num); | | my @arr = split("", join(" ", @nums)); | | my @comb; | | spliter(\@arr, $#nums, 0, 0, \@comb); | | grep { gen_exp( $_, $#$_, 0 ) } @comb; | | | | for my $k (sort {$a <=> $b} keys %hash) { | | printf "%s\n", $hash{$k}; | | } | | | | sub gen_exp | | { | | our @op, our %hash; | | my ($nums, $limit, $lv ) = @_; | | | | if ($lv >= $limit) { | | my $res; | | my $exp = $nums->[0]; | | $exp=~s/\d+/Math::BigRat->new(\"$&\/1\")/g; | | $exp=~s/\*/ * /g; | | eval("\$res = $exp"); | | return if $res == inf or $res == -inf or $res eq NaN; | | my $val = $res->as_float(); | | return unless int($val) == $val and $val >= 0; | | $hash{$val} = $res ."=". $nums->[0] unless ( exists $hash{$res} ); | | return; | | } | | | | my $pick = enum($nums); | | for my $e ( @$pick ) { | | for my $op ( @op ) { | | my @tf = ($e->[0], $op, $e->[1]); | | gen_exp(["(". join("", @tf) .")", @{$e->[2]} ], $limit, $lv+1 ); | | } | | } | | } | | | | sub enum | | { | | my ( $nums ) = @_; | | my $last = $#$nums; | | my $res = []; | | for my $a ( 0 .. $last ) { | | for my $b ( 0 .. $last-1 ) { | | my @tmpr = @$nums; | | push @$res, [splice(@tmpr,$a,1), splice(@tmpr,$b,1), [@tmpr] ]; | | } | | } | | return $res; | | } | | | | sub spliter | | { | | my ($nums, $limit, $pos, $lv, $comb) = @_; | | if ( $lv >= $limit ) { | | push @$comb, [ split(" ", join("", @$nums)) ]; | | return; | | } | | | | for my $id ( $pos+1 .. $#$nums ) { | | if ( $nums->[$id] eq " " ) { | | spliter( [@$nums], $limit, $id, $lv+1, $comb ); | | $nums->[$id] = ""; | | spliter( [@$nums], $limit, $id, $lv+1, $comb ); | | } | | } | | }COPY |
|