本帖最后由 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 );
- }
- }
- }
复制代码
|