「デートの相手」の論理パズルをJavaで解いてみました。(^_^;
「デートの相手」
とあるアパートに住んでいる独身10人は男性5人、女性5人で1階から5階までの各階に2人ずつ住んでいます。この5人の男性(A男、B男、C男、D男、E男)はこの5人の女性(P子、Q子、R子、S子、T子)といつもデートしています。(デートの相手は常に一定で一人。つまりデートは5組で組み合わせは固定)
以下の手がかりからどの階に誰が住み、誰と誰がデートしているのか?分かるかな?
1、A男とS子は同じ階に住んでいます。そして二人はその階より下の階の人とデートをしています。
2、Q子のデートの相手はQ子より下の階に住んでいます。でも3階ではありません。
3、B男のデートの相手(R子ではない)はB男よりも下の階に住んでいます。
4、D男は1階に住んでいません。D男のデートの相手は5階に住んでいません。
5、E男のデートの相手はE男よりも下の階に住んでいます。
6、R子と同じ階に住む男性はその階よりも上の階に住んでいる女性とデートしています。この女性とR子のデートの相手は異なる階に住んでいます。
7、B男と同じ階の男性はその階より上の階の女性とデートしています。
8、T子は1階に住んでいません。そしてデートの相手はE男ではありません。
ただし、名前が煩わいしいので、次のように「アルファベット+男」、「アルファベット+子」に改名しました。
男性:(アダム、リーオ、ミッチ、ニック、サム) → (A男、B男、C男、D男、E男)
女性:(リー、マリー、ステイシー、スーザン、タミー) → (P子、Q子、R子、S子、T子)5階:[住人(相手)] [住人(相手)]
4階:[住人(相手)] [住人(相手)]
3階:[住人(相手)] [住人(相手)]
2階:[住人(相手)] [住人(相手)]
1階:[住人(相手)] [住人(相手)]
※住人:大文字; 相手:小文字
論理パズル101―推理の楽しさ、ひらめきの快感 (ブルーバックス)
- 作者: デル・マガジンズ社,小野田博一
- 出版社/メーカー: 講談社
- 発売日: 1993/10/20
- メディア: 新書
- 購入: 4人 クリック: 30回
- この商品を含むブログ (16件) を見る
● CouplePuzz.java
/* * CouplePuzz.java */ class CouplePuzz { // 順列生成 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); } // 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を返す. } // b[]のyに対応するa[]のxを求めるメソッド static char getXOf(char[] a, char[] b, char y){ int n = getPos(b,y); if(n< 0) return('\0'); // ないときは、'\0'を返す. else return(a[n]); // あるときは、b[]のyに対するa[]のxを返す. } // 男性かどうか調べるメソッド static boolean isMan(char x){ return(x< 'P'); } // b[]のyに対応するa[]の要素と同じ値をもつyでないb[]の要素を求めるメソッド static char getAnotherOfSame(char[] a, char[] b, char y){ char c = getXOf(a,b,y); for(int i = 0; i< a.length; i++) if(a[i]==c && b[i]!=y) return(b[i]); // あるときは、それを返す. return('\0'); // ないときは、'\0'を返す. } // 長すぎるので改名 static char toLower(char c) { return Character.toLowerCase(c); } static int cToI (char c) { return Integer.parseInt(""+c); } public static void main(String[] args) { final String RESID = "ABCDEPQRST"; // 固定 final String FLOOR = "1122334455"; // 要素を昇順にソートしたもの final String WOMEN = "PQRST"; // 以下同様 char[] resid = RESID.toCharArray(); // 住人(固定) char[] floor = FLOOR.toCharArray(); // 階 char[] women = WOMEN.toCharArray(); // 女性 char[] partn = new char[10]; // デートの相手 long tm = System.nanoTime(); // Timer Start floor = FLOOR.toCharArray(); do{ //--- floor loop ---// if(!(getXOf(floor,resid,'A')==getXOf(floor,resid,'S'))) continue; // 条件1-1 if(!(getXOf(floor,resid,'D')!='1')) continue; // 条件4-1 char s = getAnotherOfSame(floor,resid,'R'); // R子と同じ階の住人 if(!(isMan(s))) continue; // 条件6-1 char t = getAnotherOfSame(floor,resid,'B'); // B男と同じ階の住人 if(!(isMan(t))) continue; // 条件7-1 if(!(getXOf(floor,resid,'T')!='1')) continue; // 条件8-1 women = WOMEN.toCharArray(); do{ //--- women loop ---// for(int i = 0; i< 10; i++) // Set Partn partn[i] = (i< 5) ? women[i] : getXOf(resid,women,resid[i]); if(!(getXOf(floor,resid,'A')> getXOf(floor,partn,'A'))) continue; // 条件1-2 if(!(getXOf(floor,resid,'S')> getXOf(floor,partn,'S'))) continue; // 条件1-3 if(!(getXOf(floor,resid,'Q')> getXOf(floor,partn,'Q'))) continue; // 条件2-1 if(!(getXOf(floor,partn,'Q')!='3')) continue; // 条件2-2 if(!(getXOf(floor,resid,'B')> getXOf(floor,partn,'B'))) continue; // 条件3-1 if(!(getXOf(partn,resid,'B')!='R')) continue; // 条件3-2 if(!(getXOf(floor,partn,'D')!='5')) continue; // 条件4-2 if(!(getXOf(floor,resid,'E')> getXOf(floor,partn,'E'))) continue; // 条件5 if(!(getXOf(floor,resid,s)< getXOf(floor,partn, s ))) continue; // 条件6-2 if(!(getXOf(floor,partn,s)!=getXOf(floor,partn,'R'))) continue; // 条件6-3 if(!(getXOf(floor,resid,t)< getXOf(floor,partn,t))) continue; // 条件7-2 if(!(getXOf(partn,resid,'T')!='E')) continue; // 条件8-2 // チェックを潜り抜けたものだけを表示 System.out.printf("R: %s\n",new String(resid)); System.out.printf("F: %s\n",new String(floor)); System.out.printf("P: %s\n",new String(partn).toLowerCase()); System.out.println(); // 相手は小文字で表示 // 階ごとに並べ直す for(int i = 5; i> 0; i--){ System.out.print(i+": "); for(int j = 0; j< 10; j++) if(cToI(floor[j])==i) System.out.printf("[%c(%c)]",resid[j],toLower(partn[j])); System.out.println(); } }while(nextPerm(women,5,5)); }while(nextPerm(floor,10,10)); tm = System.nanoTime()-tm; // Timer Stop System.out.printf("Runtime : %.3f [sec]\n",(double)tm/1e9); } }
●実行結果
R: ABCDEPQRST F: 4313525142 P: rtqspecadb 5: [E(p)][Q(c)] 4: [A(r)][S(d)] 3: [B(t)][D(s)] 2: [P(e)][T(b)] 1: [C(q)][R(a)] Runtime : 0.081 [sec]
※参考URL
http://stackoverflow.com/questions/5447580/tolowercasechar-method
http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1329996768
http://qiita.com/shaunkawano/items/b8bdd9517e293d0a1adb
- 作者: 中山清喬,国本大悟
- 出版社/メーカー: インプレス
- 発売日: 2014/08/07
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (19件) を見る
- 作者: 柴田望洋
- 出版社/メーカー: SBクリエイティブ
- 発売日: 2007/08/08
- メディア: 単行本
- 購入: 16人 クリック: 271回
- この商品を含むブログ (55件) を見る
- 作者: 川場隆
- 出版社/メーカー: 秀和システム
- 発売日: 2015/03/25
- メディア: 単行本
- この商品を含むブログを見る