Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 帮我完成应用程序的最后一部分?它解决任何倒计时数字游戏在第四频道通过蛮力迫使每一个可能的方程_Perl_Permutation - Fatal编程技术网

Perl 帮我完成应用程序的最后一部分?它解决任何倒计时数字游戏在第四频道通过蛮力迫使每一个可能的方程

Perl 帮我完成应用程序的最后一部分?它解决任何倒计时数字游戏在第四频道通过蛮力迫使每一个可能的方程,perl,permutation,Perl,Permutation,对于那些不熟悉游戏的人。给你8个数字,你必须使用+、-、/和*,达到目标 因此,如果目标是254,而你的游戏号码是2,50,5,2,1,那么你应该正确回答这个问题,说5*50=250。那么2+2等于4。再加上这个,得到254 以下是一些游戏视频: 基本上,我通过为数字和符号的所有烫发生成所有大小的烫发,并使用基本inflix计算器来计算解决方案,从而对游戏进行暴力 但是,它包含一个缺陷,因为所有解决方案都按以下方式解决:(((1+1)*2)*3)*4)。它不会改变括号,而且会让我头疼 所以我

对于那些不熟悉游戏的人。给你8个数字,你必须使用+、-、/和*,达到目标

因此,如果目标是254,而你的游戏号码是2,50,5,2,1,那么你应该正确回答这个问题,说5*50=250。那么2+2等于4。再加上这个,得到254

以下是一些游戏视频:

基本上,我通过为数字和符号的所有烫发生成所有大小的烫发,并使用基本inflix计算器来计算解决方案,从而对游戏进行暴力

但是,它包含一个缺陷,因为所有解决方案都按以下方式解决:(((1+1)*2)*3)*4)。它不会改变括号,而且会让我头疼

所以我不能解所有的方程。例如,给定

16的目标和数字1,1,1,1,1,1,1,1,1,当它应该执行时失败(1+1+1+1)*(1+1+1+1)=16

我希望有人能用任何语言帮我完成这件事

这是我到目前为止写的:

 #!/usr/bin/env perl

use strict;
use warnings;

use Algorithm::Permute;

# GAME PARAMETERS TO FILL IN
my $target = 751;
my @numbers = ( '2', '4', '7', '9', '1', '6', '50', '25' );


my $num_numbers = scalar(@numbers);

my @symbols = ();

foreach my $n (@numbers) {
    push(@symbols, ('+', '-', '/', '*'));
}

my $num_symbols = scalar(@symbols);

print "Symbol table: " . join(", ", @symbols);

my $lst = [];
my $symb_lst = [];

my $perms = '';
my @perm = ();

my $symb_perms = '';
my @symb_perm;

my $print_mark = 0;
my $progress = 0;
my $total_perms = 0;

my @closest_numbers;
my @closest_symb;
my $distance = 999999;

sub calculate {
    my @oprms = @{ $_[0] };
    my @ooperators = @{ $_[1] };

    my @prms = @oprms;
    my @operators = @ooperators;

    #print "PERMS: " . join(", ", @prms) . ", OPERATORS: " . join(", ", @operators);

    my $total = pop(@prms);

    foreach my $operator (@operators) {
        my $x = pop(@prms);

        if ($operator eq '+') {
            $total += $x;
        }
        if ($operator eq '-') {
            $total -= $x;
        }
        if ($operator eq '*') {
            $total *= $x;
        }
        if ($operator eq '/') {
            $total /= $x;
        }
    }
    #print "Total: $total\n";

    if ($total == $target) {
        #print "ABLE TO ACCURATELY SOLVE WITH THIS ALGORITHM:\n";
        #print "PERMS: " . join(", ", @oprms) . ", OPERATORS: " . join(", ", @ooperators) . ", TOTAL=$total\n";
        sum_print(\@oprms, \@ooperators, $total, 0);
        exit(0);
    }

    my $own_distance = ($target - $total);
    if ($own_distance < 0) {
        $own_distance *= -1;
    }

    if ($own_distance < $distance) {
        #print "found a new solution - only $own_distance from target $target\n";
        #print "PERMS: " . join(", ", @oprms) . ", OPERATORS: " . join(", ", @ooperators) . ", TOTAL=$total\n";
        sum_print(\@oprms, \@ooperators, $total, $own_distance);
        @closest_numbers = @oprms;
        @closest_symb = @ooperators;
        $distance = $own_distance;
    }

    $progress++;
    if (($progress % $print_mark) == 0) {
        print "Tested $progress permutations. " . (($progress / $total_perms) * 100) . "%\n";
    }
}

sub factorial {
    my $f = shift;
    $f == 0 ? 1 : $f*factorial($f-1);
}

sub sum_print {
    my @prms = @{ $_[0] };
    my @operators = @{ $_[1] };
    my $total = $_[2];
    my $distance = $_[3];
    my $tmp = '';

    my $op_len = scalar(@operators);

    print "BEST SOLUTION SO FAR: ";
    for (my $x = 0; $x < $op_len; $x++) {
        print "(";
    }

    $tmp = pop(@prms);
    print "$tmp";

    foreach my $operator (@operators) {
        $tmp = pop(@prms);
        print " $operator $tmp)";
    }

    if ($distance == 0) {
        print " = $total\n";
    }
    else {
        print " = $total (distance from target $target is $distance)\n";
    }
}

# look for straight match
foreach my $number (@numbers) {
    if ($number == $target) {
        print "matched!\n";
    }
}

for (my $x = 1; $x < (($num_numbers*2)-1); $x++) {
    $total_perms += factorial($x);
}

print "Total number of permutations: $total_perms\n";
$print_mark = $total_perms / 100;
if ($print_mark == 0) {
    $print_mark = $total_perms;
}

for (my $num_size=2; $num_size <= $num_numbers; $num_size++) {
    $lst = \@numbers;
    $perms = new Algorithm::Permute($lst, $num_size);

    print "Perms of size: $num_size.\n";

    # print matching symb permutations
    $symb_lst = \@symbols;
    $symb_perms = new Algorithm::Permute($symb_lst, $num_size-1);

    while (@perm = $perms->next) {
        while (@symb_perm = $symb_perms->next) {
            calculate(\@perm, \@symb_perm);
        }

        $symb_perms = new Algorithm::Permute($symb_lst, $num_size-1);
    }
}

print "exhausted solutions";
print "CLOSEST I CAN GET: $distance\n";
sum_print(\@closest_numbers, \@closest_symb, $target-$distance, $distance);
exit(0);

是Javaapplet()和Javascript版本。

建议使用反向波兰符号非常好

如果有N=5个数字,则模板为

{num} {num} {ops} {num} {ops} {num} {ops} {num} {ops}
在任何地点都可以有零到N次操作,尽管总数为N-1。你只需要尝试不同的数字和操作位置

((1+1)+1)+1)*((1+1)+1)+1)=16
解决方案将在您尝试时找到

1 1 + 1 + 1 + 1 1 + 1 + 1 + *
更新:可能不太好,因为找到上述内容可能需要43370173600次尝试。使用以下方法获得该编号:

use strict;
use warnings;

{
   my %cache = ( 0 => 1 );
   sub fact { my ($n) = @_; $cache{$n} ||= fact($n-1) * $n }
}


{
   my %cache;
   sub C {
      my ($n,$r) = @_;
      return $cache{"$n,$r"} ||= do {
         my $i = $n;
         my $j = $n-$r;
         my $c = 1;
         $c *= $i--/$j-- while $j;
         $c
      };
   }
}

my @nums = (1,1,1,1,1,1,1,1);

my $Nn = 0+@nums;  # Number of numbers.
my $No = $Nn-1;    # Number of operators.

my $max_tries = do {
   my $num_orderings = fact($Nn);
   {
      my %counts;
      ++$counts{$_} for @nums;
      $num_orderings /= fact($_) for values(%counts);
   }

   my $op_orderings = 4 ** $No;

   my $op_placements = 1;
   $op_placements *= C($No, $_) for 1..$No-1;

   $num_orderings * $op_orderings * $op_placements
};

printf "At most %.f tries needed\n", $max_tries;

你不想要排列;您需要创建每个可能的二叉树,将给定的数字作为叶子,然后为节点分配运算符,直到找到答案。忘记括号,使用:2 3+4 2-*在我看来,您可以从目标向后工作。从中减去游戏编号整数,然后将其他整数除以目标,直到得到与游戏编号匹配的因子列表。
use strict;
use warnings;

{
   my %cache = ( 0 => 1 );
   sub fact { my ($n) = @_; $cache{$n} ||= fact($n-1) * $n }
}


{
   my %cache;
   sub C {
      my ($n,$r) = @_;
      return $cache{"$n,$r"} ||= do {
         my $i = $n;
         my $j = $n-$r;
         my $c = 1;
         $c *= $i--/$j-- while $j;
         $c
      };
   }
}

my @nums = (1,1,1,1,1,1,1,1);

my $Nn = 0+@nums;  # Number of numbers.
my $No = $Nn-1;    # Number of operators.

my $max_tries = do {
   my $num_orderings = fact($Nn);
   {
      my %counts;
      ++$counts{$_} for @nums;
      $num_orderings /= fact($_) for values(%counts);
   }

   my $op_orderings = 4 ** $No;

   my $op_placements = 1;
   $op_placements *= C($No, $_) for 1..$No-1;

   $num_orderings * $op_orderings * $op_placements
};

printf "At most %.f tries needed\n", $max_tries;