「デートの相手」の論理パズルをJavaで解いてみた。

 「デートの相手」の論理パズル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―推理の楽しさ、ひらめきの快感 (ブルーバックス)

論理パズル101―推理の楽しさ、ひらめきの快感 (ブルーバックス)

● 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

スッキリわかるJava入門 第2版 (スッキリシリーズ)

スッキリわかるJava入門 第2版 (スッキリシリーズ)

明解Java 入門編

明解Java 入門編

新わかりやすいJava入門編

新わかりやすいJava入門編