知恵袋で見つけた判断推理の出会いの問題をJavaで解いてみた。

 知恵袋で見つけた判断推理の出会いの問題Javaで解いてみました。

 A〜Dの4人はある大学の留学生でそれぞれ国籍が異なり、
アメリカ人、イギリス人、フランス人、ドイツ人のいずれかである。
 ある日の4人の相互の出会いについて次の事が分かっている。
・Aはアメリカ人に会ったがDには会わなかった
・Bはイギリス人とフランス人には会った
・Cはイギリス人には会わなかった
・Dはフランス人には会った

 たとえば、条件A-2と条件Dから、A≠「フランス人」とか、自分で考えないで済むように作ってみました。(^_^;

● Encounter1.java

/* 
 * Encounter1.java
 */

import java.util.Arrays;

class Encounter1 {
    // 順列生成
    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 String sSort(String s) {
        char[] c=s.toCharArray();
        
        Arrays.sort(c);
        return(new String(c)); 
    }
    // xがa[]の何番目にあるか調べる
    static int getPos(char[] a, char x) {
        for(int i=0; i<a.length; i++)
            if(a[i]==x) return(i);  // あるときは、0〜a.length-1を返す. 
        return(-1);                 // ないときは、-1を返す. 
    }
    
    static String setPiece(String s, int i, char t) {
        if(i< 0 || 3< i) return("");    // エラーのとき「""」を返す
        char c = s.charAt(i);
        if(c!='□' && c!=t) return(""); // '□'以外を異なる文字で上書き禁止
        return(s.substring(0,i) + t + s.substring(i+1));
    }
    
    public static void main(String[] args) {
        final String NAME   = "ABCD";       // 固定
        final String NATION = sSort("米英仏独");
        char[] name   = NAME  .toCharArray();
        char[] nation = NATION.toCharArray();   // 国、国籍
        String[] sTbl = new String[4];
        int iCount = 0;
        long tm=System.nanoTime();      // Timer Start
    do_cont:
        do{    //--- nation loop ---//
            // A,B,C,Dごとに出会い表を作成
            //       ABCD
            sTbl[0]="\□□□"; // A
            sTbl[1]="□\□□"; // B
            sTbl[2]="□□\□"; // C
            sTbl[3]="□□□\"; // D
            if((sTbl[0] = setPiece(sTbl[0],getPos(nation,'米'),'○')).equals(""))
                continue;   // 条件A-1
            if((sTbl[0] = setPiece(sTbl[0],getPos(name  ,'D'),'×')).equals(""))
                continue;   // 条件A-2
            if((sTbl[1] = setPiece(sTbl[1],getPos(nation,'英'),'○')).equals(""))
                continue;   // 条件B-1
            if((sTbl[1] = setPiece(sTbl[1],getPos(nation,'仏'),'○')).equals(""))
                continue;   // 条件B-2
            if((sTbl[2] = setPiece(sTbl[2],getPos(nation,'英'),'×')).equals(""))
                continue;   // 条件C
            if((sTbl[3] = setPiece(sTbl[3],getPos(nation,'仏'),'○')).equals(""))
                continue;   // 条件D
            // 対角線に関する線対称性をチェック
            for(int i=0; i< 4; i++){
                for(int j=i+1; j< 4; j++){
                    char c1 = sTbl[i].charAt(j), c2 = sTbl[j].charAt(i);
                    if(c1!='□' && c2!='□' && c1!=c2) continue do_cont;
                }
            }
            // チェックをくぐり抜けたものだけを表示
            iCount++;
            System.out.printf("[%2d]\n",iCount);
            System.out.println("\ " + NAME);
            System.out.println(" \" + new String(nation));
            for(int i=0; i< 4; i++)
                System.out.printf("%c%c%s\n",NAME.charAt(i),nation[i],sTbl[i]);
        }while(nextPerm(nation,4,4));
        tm=System.nanoTime()-tm;        // Timer Stop
        System.out.printf("Runtime : %.3f [sec]\n",(double)tm/1e9);
    }
}

●実行結果

[ 1]
\ ABCD
 \英米仏独
A英\○□×
B米○\○□
C仏×□\□
D独□□○\
Runtime : 0.023 [sec]