願い事の推理パズルをPythonで解いてみた。

 ネットで見つけた願い事の推理パズルの問題Pythonで解いてみました。(^_^;

 問題の概要を記号や式で表すと、次の通りです。

 願い叶い度:{100%,70%,40%,5%}
 時 間 帯:{朝,昼,夕方,夜}
 場   所:{海辺,公園,家,海中}
 言 い 方:{丁寧に,簡潔に,的を射て,英語で}
(ア) {海辺}={簡潔に}
(イ) {夕方の願い叶い度}=5[%]
(ウ) {公園での願い叶い度}=40[%]
(エ) {英語で願い事を言う場所}≠{公園}
(オ) {朝に願い事を言う場所}≠{公園}
(カ) {海中での願い叶い度}>{英語で願い事を言う時の願い叶い度}
(キ) {家で願い事をする時間帯}<{70%の願い叶い度の時間帯}
(ク) {丁寧に願い事を言う時間帯}<{海中で願い事を言う時間帯}

 ただし、等号「=」は対応関係を記号的に表しています。それから、条件に(ア)〜(ク)と名前を付けました。また、プログラムでは、次のような略号や数値を用いました。

 願い叶い度:{100%,70%,40%,5%}⇒{100,70,40,5}
 時 間 帯:{朝,昼,夕方,夜}⇒{朝,昼,夕,夜}
 場   所:{海辺,公園,家,海中}⇒{海,公,家,中}
 言 い 方:{丁寧に,簡潔に,的を射て,英語で}⇒{丁,簡,的,英}

 ちなみに、プログラムで、マトリクス表は、ラベルが整数のときは、文字化して先頭2文字を取ります。ただし、1文字のときは先頭に空白を補います。それで、「100%」のとこが「10」になっています。ラベルは初めから付けないというのもありかと思いましたが、何もないよりはちょっと変でもあった方がましということで、簡略的なものを付けることにしました。(^_^;

● Wish1.py

# coding: UTF-8
# Wish1.py

from time import time
import itertools

def toStr(lst):
    return '(%s)'%'\t'.join(['%s'%x for x in lst])

# ラベルと答えのリスト等からマトリクス表を作成
def mkMatTbl(lbl,ans):
    m,n = len(lbl),len(lbl[0])
    li = [lbl[i] for i in range(1,m)]       # 横軸ラベルの作成
    s = '  '
    for i in range(m-1):
        for j in range(n):
            t = li[i][j]
            if not isinstance(t,int): s+=t
            else: s+=('%2s'%str(t))[:2]
    print(s)
    for h in range(m-1):
        for i in range(n):
            s,t = '',lbl[-h][i]
            if not isinstance(t,int): s+=t  # 縦軸ラベルの作成
            else: s+=('%2s'%str(t))[:2]
            g = ans[-h].index(t)
            for j in range(1,m-h):
                a = ans[j][g]
                for k in range(n):
                    s+=u'O' if lbl[j][k]==a else u'X'
            print(s)

def main():
    tm = time()  # Timer Start
    D = (100,70,40,5)   # 願い叶い度(固定)
    T = u'朝昼夕夜'     # 時間帯
    L = u'海公家中'     # 場所
    W = u'丁簡的英'     # 言い方
    for t in itertools.permutations(T):
        if not  D[t.index(u'夕')]==5: continue                    # 条件(イ)
        for l in itertools.permutations(L):
            if not D[l.index(u'公')]==40: continue                # 条件(ウ)
            if not l[t.index(u'朝')]!=u'公': continue             # 条件(オ)
            if not T.index(t[l.index(u'家')])< T.index(t[D.index(70)]):
                continue                                          # 条件(キ)
            for w in itertools.permutations(W):
                if not l.index(u'海')==w.index(u'簡'): continue   # 条件(ア)
                if not l[w.index(u'英')]!=u'公': continue         # 条件(エ)
                if not D[l.index(u'中')]> D[w.index(u'英')]:      # 条件(カ)
                    continue
                if not T.index(t[w.index(u'丁')])< T.index(t[l.index(u'中')]):
                    continue                                      # 条件(ク)
                # チェックを潜り抜けたものだけを表示
                print(toStr(D))
                print(toStr(t))
                print(toStr(l))
                print(toStr(w))
                print('')
                mkMatTbl((D,T,L,W),(D,t,l,w))

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

if __name__ == '__main__':
    main()

●実行結果

(100    70      40      5)
(朝     夜      昼      夕)
(海     中      公      家)
(簡     的      丁      英)

  朝昼夕夜海公家中丁簡的英
10OXXXOXXXXOXX
70XXXOXXXOXXOX
40XOXXXOXXOXXX
 5XXOXXXOXXXXO
丁XOXXXOXX
簡OXXXOXXX
的XXXOXXXO
英XXOXXXOX
海OXXX
公XOXX
家XXOX
中XXXO
Runtime : 0.000 [sec]

※参考URL
買い物の推理パズルをPythonで解いてみた。
去年と今年の身長の推理パズルをPythonで解いてみた。
花火大会の推理パズルをPythonで解いてみた。
タワーの推理パズルをPythonで解いてみた。
昼食の推理パズルをPythonで解いてみた。
買い物の推理パズルをPythonで解いてみた。(2)
Zebra PuzzleをPythonで解いてみた。(2)









厳選推理パズルSPECIAL (MSムック)

厳選推理パズルSPECIAL (MSムック)