JavaScriptで作った小町算のプログラムをJavaに翻訳してみた。(2)

 前回のがあまりにもお粗末な結果となってしまったので、アルゴリズム辞典を参考にして、eval()を作ってみました。参考URLの「java-algo.zip」中の「Eval.java」を参考にしました。
 残念ながら、思ったほど速くなりませんでした。少し速くなりましたが、JavaScriptよりも遅いようです。ちなみに、Cでは、0.03〜0.04[秒]ぐらいでした。(^_^;

●Komachizan02.java

/* 
 * Komachizan02.java
 *  
 * □1□2□3□4□5□6□7□8□9=100
 * 
 * (1)□={"","-","+"}
 * (2)□={"","-","+","*","/"}
 * 
 */

public class Komachizan02 {
    static Eval eval = new Eval();
    
    static double eval(String s) {
        return(eval.calc(s));
    }
    
    static boolean next_rep_perm(int[] p, int[] n, int r) {
        int cy=1;
        //if(r!=p.length) return(false);
        for(int i=r-1; i>=0; i--) {
            p[i]+=cy;
            if(p[i]>=n[i]){
                p[i]=0; cy=1;
            } else
                cy=0;
        }
        if(cy==0) return(true); return(false);
    }
    
    public static void main(String[] args) {
        final int M=100;
        final int N=3;              // (1)空白と'+','-'だけ使用する場合
        //final int N=5;            // (2)空白と'+','-','*','/'を使用する場合
        final int R=9;
        final String OPR=" -+*/";
        
        char[] o=OPR.toCharArray();
        int[]  p=new int[R];
        int[]  n=new int[R];
        String f="";
        long tm=System.nanoTime();  // Timer Start
        
        for(int i=0; i< R; i++) p[i]=0;
        n[0]=2;                     // 先頭は空白か'-'とする
        for(int i=1; i< R; i++) n[i]=N;
        do{
            f=String.format("%c1%c2%c3%c4%c5%c6%c7%c8%c9",
                o[p[0]],o[p[1]],o[p[2]],o[p[3]],o[p[4]],o[p[5]],o[p[6]],o[p[7]],o[p[8]]);
            f=f.replace(" ","");
            if(eval(f)==M) System.out.println(f+"="+M);
        } while(next_rep_perm(p,n,R));
        tm=System.nanoTime()-tm;    // Timer Stop
        System.out.printf("Runtime : %.3f [sec]\n",(double)tm/1e9);
    }
}

// 式の評価。1つのファイルに収めるために、public をはずした。
// 出来るだけ元の形を崩さないようにした。ただし、static をはずした。
class Eval {
    int ch;                        // static をはずした。
    int pos;
    String sExpr;

    void error(String s) {  // エラー処理
        // static をはずしただけでオリジナルと同じにて省略
    }

    // 文字列から読み込むようにした。
    void readCh() {  // 1文字を読む。空白は読み飛ばす。
        do {
            ch = sExpr.charAt(pos++);
        } while (ch == ' ' || ch == '\t' || ch == '\r');
    }

    double number() { // 数
        // static をはずしただけでオリジナルと同じにて省略
    }

    double factor() { // 因子
        // static をはずしただけでオリジナルと同じにて省略
    }

    double term() { // 項
        // static をはずしただけでオリジナルと同じにて省略
    }

    double expression() { // 式
        // static をはずしただけでオリジナルと同じにて省略
    }

    // main() を書き直して、double calc() に改名
    double calc(String src) {
        pos=0;
        sExpr=src+'\n';
        readCh();
        double x = expression();

        if (ch != '\n') error("文法の間違いがあります");
        return x;
    }
}

●実行結果

123-45-67+89=100
123-4-5-6-7+8-9=100
123+45-67+8-9=100
123+4-5+67-89=100
12-3-4+5-6+7+89=100
12+3-4+5+67+8+9=100
12+3+4+5-6-7+89=100
1+23-4+56+7+8+9=100
1+23-4+5+6+78-9=100
1+2+34-5+67-8+9=100
1+2+3-4+5+6+78+9=100
-1+2-3+4+5+6+78+9=100
Runtime : 0.467 [sec]

※参考URL
『Javaによるアルゴリズム事典』サポートページ
小町算をJavaScriptで解いてみた(2)
JavaScriptで作った小町算のプログラムをJavaに翻訳してみた。

C言語による最新アルゴリズム事典 (ソフトウェアテクノロジー)

C言語による最新アルゴリズム事典 (ソフトウェアテクノロジー)

Javaによるアルゴリズム事典

Javaによるアルゴリズム事典