やはり、スクリプト系だとすごく楽でいいですね。
私がCで作ったのは、こちらです。できるだけ、コピペで楽して作ろうとしても大変です。(^_^;
下記の関数電卓の C ソースを使わせていただきました。 main を「#if 0 〜 #endif」で無効化するだけで使えます。ただし、point とか answer とか expr をグローバル変数に使っているので、衝突しないように注意が必要です。(^_^;
コンパイルは、「Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland」を使いました。警告が出ますが大丈夫です。気になる場合は、_calc.c の double getValue(void) 関数の strlen(expr) を 2 か所 (int)strlen(expr) のようにキャストしてください。
順列生成は、一般の順列生成をアルゴリズム辞典からコピペして少し変えて作ってもよかったのですが説明が大変なので5つの順列専用にしました。
/* Quiz_Opr.c */ #include <stdio.h> /* calc.c の main を #if 0 〜 #endif で無効化したソース */ #include "_calc.c" /* _calc.c を使いやすくするための関数 */ double Evaluate(char *src) { point = 0; strcpy(expr,src); return(getValue()); } /* 左辺と右辺を得る */ void GetLhsAndRhs(char *s,char *l,char *r) { while(*s!='=') *l++=*s++; *l='\0',s++; while(*s) *r++=*s++; *r='\0'; } /* 5つの順列生成 */ int Perm[128][5]; /* 少し多めに余裕をもって */ void GenPerm5(void) { int i,j,k,m,n; int count = 0; for(i=0; i<5; i++){ for(j=0; j<5; j++){ if(j==i) continue; /* 前と同じものはスキップ */ for(k=0; k<5; k++){ if(k==i||k==j) continue; /* スキップ */ for(m=0; m<5; m++){ if(m==i||m==j||m==k) continue; /* スキップ */ for(n=0; n<5; n++){ if(n==i||n==j||n==k||n==m) continue; /* スキップ */ Perm[count][0]=i; Perm[count][1]=j; Perm[count][2]=k; Perm[count][3]=m; Perm[count][4]=n; count++; } } } } } } #define Op(j) opr[Perm[i][j]] /* 略記用 */ int main(void) { char opr[8]="+-*/="; /* 少し多めに余裕をもって */ char buf[32],lhs[32],rhs[32]; int i; GenPerm5(); /* 5つの順列を生成 */ for(i=0; i<120; i++){ if(Op(4)=='/') continue; /* ÷0は_calc.cでエラーになるのでスキップ */ sprintf(buf,"5%c4%c3%c2%c1%c0",Op(0),Op(1),Op(2),Op(3),Op(4)); printf("%s",buf); GetLhsAndRhs(buf,lhs,rhs); /* 左辺と右辺を得る */ if(Evaluate(lhs)==Evaluate(rhs)) printf(" <--- Hit\n"); else printf("\n"); } return(0); }
※参考URL
http://q.hatena.ne.jp/1296542184
http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1245133382
●関数電卓のマニュアル及びソースファイル
●C言語による最新アルゴリズム事典
>genperm.c
P.S.
使用した関数電卓のソース calc.c がリンク切れになっているようなので、EZFUNC のソースを使って Evaluate 関数等を書き直してみました。(^_^;
●ちょっと前のクイズ(3)