知恵袋で見つけた判断推理の出会いの問題を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]