プログラムの実行結果は以下の通り。
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;
}