知恵袋の「ウソつき問題」をPythonで解いてみた。(10)

 知恵袋の「ウソつき問題」をPythonで解いてみました。(^_^;
 エイプリルフールの日に、書く予定でしたが、知恵袋で問題を見つけるのに時間がかかってしまいました。(^_^;

 A ~ D の4 人は1 組~ 4 組までのいずれかの生徒で、同じクラスの者はいません。
次のうち、A とB はうそをいい、C とD は本当のことを言っています。
このとき正しいものはどれでしょうか。
  1 組の生徒「私はB である」
  2 組の生徒「B は3 組の生徒である」
  3 組の生徒「A は3 組の生徒である」
  4 組の生徒「私はD である」
1  A は3 組の生徒である。
2  B は2 組の生徒である。
3  C は3 組の生徒である。
4  D は2 組の生徒である。
5  A は1 組の生徒である。

 「cN in 'CD'」で発言者cN(N=1~4)が正直者かどうかを判定しました。
 自力で解く場合、「私は嘘つきA(B)である」と言っている人は、A(B)ではない方の嘘つきB(A)になるということに気づけば後は簡単ですね。

● Liar10.py

# coding: UTF-8
# Liar10.py

import itertools
from time import time

# 論理等価Eqv
def Eqv(p,q):
    return not(p^q)

# 確実にいえる選択肢を得る
def getAns(cho,lbl='12345'):
    return ','.join([lbl[i] for i in range(len(cho)) if cho[i]])

def toStr(li,sp=',',fm='%s'):
    return fm%sp.join(li)

def main():
    tm = time() # Timer Start
    choices = [True]*5
    P = 'ABCD'
    for p in itertools.permutations(P):
        c1,c2,c3,c4 = p
        if not Eqv(c1 in 'CD', c1=='B'): continue
        if not Eqv(c2 in 'CD', c3=='B'): continue
        if not Eqv(c3 in 'CD', c3=='A'): continue
        if not Eqv(c4 in 'CD', c4=='D'): continue
        pass # チェックを潜り抜けたものを表示
        print(toStr(p))
        pass # 選択肢のチェック
        choices[0] &= (c3=='A')
        choices[1] &= (c2=='B')
        choices[2] &= (c3=='C')
        choices[3] &= (c2=='D')
        choices[4] &= (c1=='A')

    print(u"∴%s"%getAns(choices))
    print("Runtime : %.3f [sec]"%(time()-tm))   # Timer Stop & Disp

if __name__ == '__main__':
    main()

●実行結果

A,C,B,D
∴5
Runtime : 0.000 [sec]

※参考URL
知恵袋の「ウソつき問題」をPythonで解いてみた。 - rscのブログ
知恵袋の「ウソつき問題」をPythonで解いてみた。(2) - rscのブログ
知恵袋の「ウソつき問題」をPythonで解いてみた。(3) - rscのブログ
知恵袋の「ウソつき問題」をPythonで解いてみた。(4) - rscのブログ
知恵袋の「ウソつき問題」をPythonで解いてみた。(5) - rscのブログ
知恵袋の「ウソつき問題」をPythonで解いてみた。(6) - rscのブログ
知恵袋の「ウソつき問題」をPythonで解いてみた。(7) - rscのブログ
知恵袋の「ウソつき問題」をPythonで解いてみた。(8) - rscのブログ
知恵袋の「ウソつき問題」をPythonで解いてみた。(9) - rscのブログ
知恵袋の「うそつき問題」をJavaで解いてみた。
ネットで見つけた「うそつき問題」をJavaで解いてみた。
ネットで見つけた「うそつき問題」を自分で解いてみた。
2つの発言の「うそつき問題」をJavaで解いてみた。