プログラムの実行結果は以下の通り。
25 55 + 25 x 5 + 55 25 + 25 x 5 + 1.187 秒
結果を普通の計算式に直すと以下のようになる。
( 22 + 55 ) x 25 + 5
プログラムのソースは以下の通り。
#include "puzutl.h" int num[] = { 2, 5}; // 使える数 int ope[] = { 0, 1/*Push*/, -1/*+*/, -2/*−*/, -3/*×*/, -4/*÷*/}; // 演算子, 0:何もしない,1:スタックに積む int used[] = {0,0}; // 数字を何個使ったか int mnum[] = { 2, 5}; // 2は2個,5は5個使える int mope = 3; // 演算子使用最大数 int nope = 0; // 演算子数 void calcRPN( int cal[], int ical) { // cal[] を逆ポーランド記法で数字と演算子が入っていると仮定し計算する。 // エラーがあれば計算を打ち切り,エラーが無ければ結果を計算する。 int bunsi[109], bunbo[109], sp = 0; for( int i=0; i< ical; i++) { if( cal[i] > 0) { // 数字なのでスタックに積む bunsi[sp] = cal[i]; bunbo[sp] = 1; sp++; } else if( sp >= 2 && cal[i] < 0) { // 演算子なので計算する。但し数字が2つあることが前提。 int op = cal[i]; int m = bunsi[sp-2], n = bunbo[sp-2]; // m/n op t/s int t = bunsi[sp-1], s = bunbo[sp-1]; if( op == -1/*+*/) { --sp; bunsi[sp-1] = m*s + n*t; bunbo[sp-1] = s*n;} if( op == -2/*−*/) { --sp; bunsi[sp-1] = m*s - n*t; bunbo[sp-1] = s*n;} if( op == -3/*×*/) { --sp; bunsi[sp-1] = m*t ; bunbo[sp-1] = s*n;} if( op == -4/*÷*/) { --sp; bunsi[sp-1] = m*s ; bunbo[sp-1] = n*t;} } else { // 計算不能 return; } } if( bunbo[0] != 0 && (bunsi[0] / bunbo[0]) == 2005 && (bunsi[0] % bunbo[0]) == 0) { // 演算結果が2005になったら答えを出力 char sope[] = { '@', '+', '-', 'x', '/'}; for( int i=0; i< ical; i++) { if( cal[i] > 0) ps( "%d ", cal[i]); else if( cal[i] < 0) ps( "%c ", sope[-cal[i]]); else ps( "ERROR\n"); } ps( "\n"); } } void checkprint( int buf[]) { // buf[]に入っている数字と演算子をスタックに積んで逆ポーランド記法と見なし計算する int n = 0; int ical = 0; int cal[30]; for( int i=0; i< 14; i++) { if( buf[i] == 1) { cal[ical++] = n; // 現在値をスタックに積む n = 0; } else if( buf[i] > 0) { n *= 10; // 数字は前の数字と合わせて新しい値になる n += buf[i]; } else if( buf[i] < 0) { // 演算子が出現した cal[ical++] = n; // 演算子の前の数字をスタックに積み, cal[ical++] = buf[i]; // 演算子もスタックに積む n = 0; // } } calcRPN( cal, ical); } int main( int argc, cstring argv[]) { int buf[30]; ProcTime pt; pt.start(); for( int a=0; a< 2; a++) { used[a]++; buf[0] = num[a]; for( int b=0; b< 6; b++) { if( ope[b] < 0 && nope >= mope) continue; if( ope[b] < 0) nope++; buf[1] = ope[b]; for( int c=0; c< 2; c++) { if( used[c] >= mnum[c]) continue; used[c]++; buf[2] = num[c]; for( int d=0; d< 6; d++) { if( ope[d] < 0 && nope >= mope) continue; if( ope[d] < 0) nope++; buf[3] = ope[d]; for( int e=0; e< 2; e++) { if( used[e] >= mnum[e]) continue; used[e]++; buf[4] = num[e]; for( int f=0; f< 6; f++) { if( ope[f] < 0 && nope >= mope) continue; if( ope[f] < 0) nope++; buf[5] = ope[f]; for( int g=0; g< 2; g++) { if( used[g] >= mnum[g]) continue; used[g]++; buf[6] = num[g]; for( int h=0; h< 6; h++) { if( ope[h] < 0 && nope >= mope) continue; if( ope[h] < 0) nope++; buf[7] = ope[h]; for( int i=0; i< 2; i++) { if( used[i] >= mnum[i]) continue; used[i]++; buf[8] = num[i]; for( int j=0; j< 6; j++) { if( ope[j] < 0 && nope >= mope) continue; if( ope[j] < 0) nope++; buf[9] = ope[j]; for( int k=0; k< 2; k++) { if( used[k] >= mnum[k]) continue; used[k]++; buf[10] = num[k]; for( int l=0; l< 6; l++) { if( ope[l] < 0 && nope >= mope) continue; if( ope[l] < 0) nope++; buf[11] = ope[l]; for( int m=0; m< 2; m++) { if( used[m] >= mnum[m]) continue; used[m]++; buf[12] = num[m]; for( int n=0; n< 6; n++) { if( ope[n] < 0 && nope >= mope) continue; if( ope[n] < 0) nope++; buf[13] = ope[n]; if( nope != 0) { checkprint( buf); // 演算子は一つは無いとダメ } if( ope[n] < 0) nope--; } used[m]--; } if( ope[l] < 0) nope--; } used[k]--; } if( ope[j] < 0) nope--; } used[i]--; } if( ope[h] < 0) nope--; } used[g]--; } if( ope[f] < 0) nope--; } used[e]--; } if( ope[d] < 0) nope--; } used[c]--; } if( ope[b] < 0) nope--; } used[a]--; } pt.end(); ps( "%g 秒\n", pt.sec()); return 0; }