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

 知恵袋の「ウソつき問題」をPythonで解いてみました。(^_^;

【問】誰が正直族か文化人類学者の推理博士と一緒に論理的に推理しなさい。
 嘘つき族と正直族が住んでいるパズル島に初めて訪問した文化人類学者の推理博士は、上陸したとたん、二人の島民に会いました。一人は背が高く、もう一人は小柄な人でした。むろん、この二人が嘘つき族か正直族かどうかは見ただけではわかりません。
 「君は正直族かね?」と博士は、まず背の高い島民に訊いてみました。そうすると背の高い島民は「ペペール」と答えました。博士はそれが島民の言葉で、”Yes”を表すのか”No”を表すのかわからないので首をかしげていると小柄な島民が「この男はね、”Yes”と言ったんです。しかし、奴はとんでもない嘘つきですぜ!」
 さて、この二人のうち、正直族はとちらなのでしょう? 

 背の高い島民aと小柄な島民bが、嘘つき族か正直族かどうかを(False, True)で、「ペペール」cが”Yes”を表すのか”No”を表すのかを(True, False)としました。(^_^;
 プログラム中の「if not Eqv(a, Eqv(c, a)): continue」のとこは、

        if c:
            if not Eqv(a, a): continue
        else:
            if not Eqv(a, not a): continue

でも、いいですが、これを条件変形すると、

        if c:
            if not True: continue
        else:
            if not False: continue

となって、結局、「if not c: continue」と同じことになります。(^_^;
 要するに、「ペペール」cが”Yes”(True)ということになります。これに気づけば、自力で解くのは簡単ですね。

● Liar11.py

# coding: UTF-8
# Liar11.py

import itertools
from time import time

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

# 正直者をすべて得る
def getHonestMen(names,li):
    return ','.join([names[i] for i in range(len(li)) if li[i]])

def main():
    tm = time()  # Timer Start
    TF = (True,False)
    for p in itertools.product(TF,repeat=3):
        a,b,c = p
        if not Eqv(a, Eqv(c, a)): continue
        if not Eqv(b, c): continue
        if not Eqv(b, not a): continue
        pass # チェックを潜り抜けたものだけを表示
        print('正直族は、%s島民'%getHonestMen(['背の高い','小柄な'],[a,b]))

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

if __name__ == '__main__':
    main()

●実行結果

正直族は、小柄な島民
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のブログ
知恵袋の「ウソつき問題」をPythonで解いてみた。(10) - rscのブログ