ちょっと前の質問の小町算の類題をJavaで解いてみました。5555じゃなくて、1199の方です。(^_^;
数字が4つなので、括弧は多くても2つあればいいようで、f,bは、
x+y+z+w≦2の負でない整数解
に対応させればよく、これはさらに、
x+y+z+w+d=2の負でない整数解の(x,y,z,w)の部分
に帰着させることができます。
括弧のとこが難しくて、条件を継ぎ足して余計なものを削っただけの手抜きですが、まぁ、とりあえず答えを出せるようになりました。(^_^;
※参考URL
http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1352515108
http://www.hi-ho.ne.jp/yoshik-y/mathematics/m036.html
http://note.chiebukuro.yahoo.co.jp/detail/n69092
●JavaからJavaScriptを呼び出すサンプル - 昼間のメモ
●KomachiSim1.java
/* * KomachiSim1.java * */ import javax.script.*; class KomachiSim1 { static ScriptEngineManager factory = new ScriptEngineManager(); static ScriptEngine engine = factory.getEngineByName("JavaScript"); static double dEval(String sExpr) { try{ return( Double.parseDouble(engine.eval(sExpr).toString()) ); } catch(Exception e){ // System.out.println(e); return( Double.NaN ); } } static boolean nextRepPerm(int[] p, int n, int r) { int cy=1; for(int i=r-1; i>=0; i--) { p[i]+=cy; if(p[i]>=n){ p[i]=0; cy=1; } else cy=0; } if(cy==0) return(true); return(false); } // 順列生成 static boolean nextPerm(char[] p, int n, int r) { int i, j; char t; if(r <= 0 || n < r) return(false); for(i = r + 1; i <= n-1; i++) for(j = i; j >= r + 1 && p[j-1] < p[j]; j--){ t = p[j]; p[j] = p[j-1]; p[j-1] = t; // swap(p,j,j-1); } for(i = n - 1; i > 0 && p[i-1] >= p[i]; i--); if(i==0) return(false); for(j = n - 1; j > i && p[i-1] >= p[j]; j--); t = p[j]; p[j] = p[i-1]; p[i-1] = t; // swap(p,j,i-1); for(j = n - 1; i < j; i++, j--){ t = p[i]; p[i] = p[j]; p[j] = t; // swap(p,i,j); } return(true); } static boolean nextHomoPro(int[] h, int n, int r) { int i,j, k = n+r-1; String s=""; for(i=0; i< n; i++){ s+="I"; for(j=0; j< h[i]; j++) s+="O"; } s=s.substring(1); //System.out.println(s); char[] p = s.toCharArray(); if(!nextPerm(p,k,k)) return(false); //System.out.println(new String(p)); s=new String(p)+"I"; for(i=j=0; i< n; i++,j=k+1) h[i]=(k=s.indexOf("I",j))-j; return(true); } static String fb(int n) { String s = ""; for(int i=0; i< n; i++) s+="("; return(s); } static String bb(int n) { String s = ""; for(int i=0; i< n; i++) s+=")"; return(s); } public static void main(String[] args) { final int[] BRACKET = {0,0,0,0,2}; // 要素を昇順にソートしたもの final String NUM = "1199"; // 〃 final int[] Z = {0,0,0}; final String OPR = "+-*/"; // nextRepPermのはソート不要 int [] f = (int[])BRACKET.clone(); int [] b = (int[])BRACKET.clone(); int [] p = (int[])Z.clone(); char[] o = OPR.toCharArray(); char[] n = NUM.toCharArray(); String sExpr=""; long tm=System.nanoTime(); // Timer Start do{ //--- f loop ---// b = (int[])BRACKET.clone(); do{ //--- b loop ---// sExpr=String.format("%s1%s+%s1%s+%s1%s+%s1%s", fb(f[0]),bb(b[0]), fb(f[1]),bb(b[1]), fb(f[2]),bb(b[2]), fb(f[3]),bb(b[3])); if(sExpr.contains("(1)")) continue; if(f[0]> 0 && b[3]> 0) continue; if(sExpr.contains("((1") && sExpr.contains("1))")) continue; if(dEval(sExpr)==Double.NaN) continue; p = (int[])Z.clone(); do{ //--- p loop ---// n = NUM.toCharArray(); do{ //--- n loop ---// sExpr=String.format("%s%c%s%c%s%c%s%c%s%c%s%c%s%c%s", fb(f[0]),n[0],bb(b[0]),o[p[0]], fb(f[1]),n[1],bb(b[1]),o[p[1]], fb(f[2]),n[2],bb(b[2]),o[p[2]], fb(f[3]),n[3],bb(b[3])); if(sExpr.contains("(1*9)")) continue; if(sExpr.contains("(1/9)")) continue; if(sExpr.contains("(9*1)")) continue; if(sExpr.contains("(9/1)")) continue; if(dEval(sExpr)==10) // JavaScriptのevalだから「.0」は不要 System.out.println(sExpr+"==10"); }while(nextPerm(n,4,4)); }while(nextRepPerm(p,4,3)); }while(nextHomoPro(b,5,2)); }while(nextHomoPro(f,5,2)); tm=System.nanoTime()-tm; // Timer Stop System.out.printf("Runtime : %.3f [sec]\n",(double)tm/1e9); } }
●実行結果
9*(1+1/9)==10 9*(1/9+1)==10 (1+1/9)*9==10 (1/9+1)*9==10 Runtime : 4.853 [sec]
P.S.
後に、この小町算の類題は、「テンパズル(10 Puzzle)」とか「メイクテン(Make 10)」とか「切符番号の問題」と呼ばれていることがわかりました。(^_^;
●10 Puzzleを解くプログラムをPythonで作ってみた。 (3)
- 作者: チャート研究所
- 出版社/メーカー: 数研出版
- 発売日: 2012/02/14
- メディア: 単行本
- 購入: 2人 クリック: 1回
- この商品を含むブログ (7件) を見る
- 作者: 川場隆
- 出版社/メーカー: 秀和システム
- 発売日: 2009/10/23
- メディア: 単行本
- 購入: 14人 クリック: 162回
- この商品を含むブログ (33件) を見る