知恵袋で見つけた判断推理の円卓問題をPythonで解いてみた。(2)

 知恵袋で見つけた判断推理の円卓問題Pythonで解いてみました。(^_^;

 円いテーブルにA〜Hの8人が座り、コーヒー、紅茶、ジュースの中から一つずつ注文した。ア〜オのことが分かっているとき、確実にいえるのはどれか。
ア.コーヒー、紅茶、ジュースを注文した者の数はそれぞれ異なっており、また、隣り合った者は異なるものを注文した。
イ.Aは紅茶を注文し、Aの正面の者はコーヒーを注文した。
ウ.Bはコーヒーを注文し、また、BとCとの間に2人が座っている。
エ.Dが注文したものと、Dの正面に座った者が注文したものとは異なっていた。
オ.Eの正面に座った者の両隣の者は、ジュースを注文した。
1.Aの隣にEが座っている。
2.Bの隣にFが座っている。
3.Dの隣にCが座っている。
4.Gが注文した飲み物は、紅茶である。
5.Hが注文した飲み物は、ジュースである。

 円卓の座席に反時計回りに次のような座席番号を付けました。また、円順列を考えるので、Aを座席番号[0]に固定して考えました。飲み物は、コーヒーをc、紅茶をt、ジュースをjとしました。

       [0]
   [1]     [7]

 [2]         [6]

   [3]     [5]
       [4]

 ちなみに、Aを座席番号[0]に固定しているので、条件イは、飲み物のタプルのリストを作成するときに用いることもできます。そうすると、少し速くなります。(^_^;

● RoundTableCh2.py

# coding: UTF-8
# RoundTableCh2.py

import itertools
import re
from time import time

def PrintResult(c,p,q):
    print( '[%2d]'%c)
    print( '%s'%''.join(p))
    print( '%s'%''.join(q))
    print(u'      %s     '% p[0])
    print(u'  %s/⌒\%s '%(p[1],p[7]))
    print(u' %s|    |%s'%(p[2],p[6]))
    print(u'  %s\_/%s '%(p[3],p[5]))
    print(u'     %s      '% p[4])

def main():
    tm=time()  # Timer Start
    choices = [False]*5
    P = 'ABCDEFGH'
    Q = 'ctj'       # 飲み物(c:コーヒー, t:紅茶, j:ジュース)
    drinks = []     # 条件アから飲み物のタプルのリストを作成
    for q in itertools.product(Q,repeat=8):
        nc,nt,nj = q.count('c'), q.count('t'), q.count('j')
        if (nc-nt)*(nt-nj)*(nj-nc)==0: continue
        t = ''.join(q)*2
        if 'cc' in t or 'tt' in t or 'jj' in t: continue
        drinks.append(q)
##    print(drinks)
    count = 0
    for p in itertools.permutations(P):
        if p[0]!='A': continue      # Aを固定
        s = ''.join(p)              # 座席表
        t = s*2
        if not re.search(r'B..C|C..B',t): continue  # 条件ウ
        # 座席番号
        a,b,c,d = 0,           p.index('B'),p.index('C'),p.index('D')
        e,f,g,h = p.index('E'),p.index('F'),p.index('G'),p.index('H')
        for q in drinks:
            if q[a]!='t':        continue           # 条件イ
            if q[(a+4)%8]!='c':  continue           # 条件イ
            if q[b]!='c':        continue           # 条件ウ
            if q[d]==q[(d+4)%8]: continue           # 条件エ
            if q[(e+3)%8]!='j':  continue           # 条件オ
            if q[(e+5)%8]!='j':  continue           # 条件オ
            # チェックを潜り抜けたものだけを表示
            count+=1
            PrintResult(count,p,q)
            # 選択肢のチェック
            if count==1: choices = [True]*5
            choices[0] &= re.search(r'AE|EA',t)!=None
            choices[1] &= re.search(r'BF|FB',t)!=None
            choices[2] &= re.search(r'DC|CD',t)!=None
            choices[3] &= (q[g]=='t')
            choices[4] &= (q[h]=='j')

    s = ""
    for c in choices:
        if c : s+=" %s"%(choices.index(c)+1)
    print(u"∴%s"%s)
    print("Runtime : %.3f [sec]"%(time()-tm))   # Timer Stop & Disp

if __name__ == '__main__':
    main()

●実行結果

[ 1]
ACEFDGBH
tjcjcjcj
      A     
  C/⌒\H 
 E|    |B
  F\_/G 
     D      
[ 2]
ACEFDHBG
tjcjcjcj
      A     
  C/⌒\G 
 E|    |B
  F\_/H 
     D      

…(省略)…

[24]
AHECDGBF
tjcjcjcj
      A     
  H/⌒\F 
 E|    |B
  C\_/G 
     D      
∴ 5
Runtime : 0.235 [sec]

※参考URL
判断推理の円卓問題をPythonで解いてみた。
知恵袋で見つけた判断推理の円卓問題をPythonで解いてみた。
知恵袋で見つけた判断推理の円卓問題をPythonで解いてみた。(3)