#!/usr/local/bin/perl # check.pl # Written by ODASAN, 2003/05/18 # パラメータとして、4桁の数字と合計値を # check.pl 1 2 3 4 10 のように指定する。 # 10以上の数でも可。 $equal=$ARGV[4]; # この値になる演算式を求めるのである $allow = 0.001; # 小数計算で想定される誤差の許容範囲 $under = $equal-$allow; # 等しいとみなす下限 $over = $equal+$allow; # 等しいとみなす上限 $counter = 0; # いくつあるか? @exp = ('(($a op1 $b) op2 $c) op3 $d', # 式のパターンは5通り '($a op1 $b) op2 ($c op3 $d)', '$a op1 ($b op2 $c) op3 $d', '$a op1 (($b op2 $c) op3 $d)', '$a op1 ($b op2 ($c op3 $d))'); @ope = ('+', '-', '*', '/'); # 演算子は4通り for ($ai=0;$ai<4;$ai++) { # $a $a=$ARGV[$ai]; for ($bi=0;$bi<4;$bi++) { # $b if ($bi != $ai) { $b=$ARGV[$bi]; } else { next; } for ($ci=0;$ci<4;$ci++) { # $c if (($ci != $ai) and ($ci != $bi)) { $c=$ARGV[$ci]; } else { next; } for ($di=0;$di<4;$di++) { # $d if (($di != $ai) and ($di != $bi) and ($di != $ci)) { $d=$ARGV[$di]; } else { next; } for ($p=0;$p<5;$p++) { # 式のパターン for ($i=0;$i<4;$i++) { # op1 for ($j=0;$j<4;$j++) { # op2 for ($k=0;$k<4;$k++) { # op3 $exp2=$exp[$p]; $exp2 =~s/op1/$ope[$i]/; # 式の書換え $exp2 =~s/op2/$ope[$j]/; $exp2 =~s/op3/$ope[$k]/; $value = eval($exp2); # ここがミソ if (($value <= $over) and ($value >= $under)) { $exp2 =~s/\$a/$a/; # 結果表示用 $exp2 =~s/\$b/$b/; $exp2 =~s/\$c/$c/; $exp2 =~s/\$d/$d/; $counter++; print ("$exp2 = $equal\n"); } } } } } } } } } print ("$counter 個ありました。\n"); exit();