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

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

 男女合わせて8人が円卓に座って会議をし、次のア〜キのことが分かっているとき
確実に言えるのはどれか。1〜5の中から選べ。
なお、このうち三人は司会者、書記、発表者のいずれかの役割を担っている。
ア.A〜Eは男性で、FGHは女性であった。
イ.女性同士は隣り合わず、また正面に向かい合って座ることもない。
ウ.司会者の正面はFで、司会者の右隣はAだった。
エ.Bは司会者も書記もしなかった。
オ.発表者とその正面のBは夫婦であった。
カ.書記の右隣も正面も女性だった。
キ.Eの一人おいた隣にDとGが座っていた。
1.Aの正面はEであった
2.Bの両隣りは女性だった
3.Fの左隣は書記であった
4.Gは書記の正面であった
5.Hは司会者の左隣であった

 円卓の座席に反時計回りに次のような座席番号を付けました。また、円順列を考えるので、Aを座席番号[0]に固定して考えました。
 担っている役割は、司会者を'c'、書記を's'、発表者を'p'、そして、役割がないものを半角スペース' 'としました。
 女性の隣接条件では、女性を'o'、男性を'x'として男女表を作成してチェックしました。
 pを名前の順列、qを役割の同じものを含む順列として回してみました。(^_^;

       [0]
   [1]     [7]

 [2]         [6]

   [3]     [5]
       [4]

● RoundTableCh3.py

# coding: UTF-8
# RoundTableCh3.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 isMan(s):
    return s in 'ABCDE'

def isWoman(s):
    return s in 'FGH'

def getSeatNum(p):
    NAME = 'ABCDEFGH'
    result = []
    for i in range(len(NAME)):
        result.append(p.index(NAME[i]))
    return result

def mkDanjoTable(s):
    result = ''
    for i in range(len(s)):
        result+=('o' if isWoman(s[i]) else 'x')
    return result

def main():
    tm = time()  # Timer Start
    choices = [False]*5
    P = 'ABCDEFGH'
    Q = 'csp     '  # 役割(c:司会者, s:書記, p:発表者)
    count = 0
    for p in itertools.permutations(P):
        if p[0]!='A': continue      # Aを固定
        s = ''.join(p)              # 座席表
        t = s*2
        DanjoTable = mkDanjoTable(t)
        if re.search(r'oo',DanjoTable):     continue    # 条件イ
        if re.search(r'o...o',DanjoTable):  continue    # 条件イ
        if not re.search(r'D.E.G|G.E.D',t): continue    # 条件キ
        # 座席番号
        a,b,c,d,e,f,g,h = getSeatNum(p)
        if (f+5)%8!=a: continue                         # 条件ウ
        for q in set(itertools.permutations(Q)):    # 同じものを含む順列
            if q[(f+4)%8]!='c': continue                # 条件ウ
            if q[b]=='c' or q[b]=='s': continue         # 条件エ
            if q[(b+4)%8]!='p': continue                # 条件オ
            if isMan(p[(b+4)%8]): continue              # 条件オ
            s = q.index('s')
            if isMan(p[(s+1)%8]): continue              # 条件カ
            if isMan(p[(s+4)%8]): continue              # 条件カ
            # チェックを潜り抜けたものだけを表示
            count+=1
            PrintResult(count,p,q)
            # 選択肢のチェック
            if count==1: choices = [True]*5
            choices[0] &= re.search(r'A...E',t)!=None
            choices[1] &= isWoman(p[b-1]) and isWoman(p[(b+1)%8])
            choices[2] &= (q[(f-1)%8]=='s')
            choices[3] &= (q[(g+4)%8]=='s')
            choices[4] &= (q[(h+1)%8]=='c')

    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]
AGBFCDHE
     spc
      A     
  G/⌒\E 
 B|    |H
  F\_/D 
     C      
[ 2]
AHDFEBGC
 ps    c
      A     
  H/⌒\C 
 D|    |G
  F\_/B 
     E      
∴ 4
Runtime : 0.135 [sec]

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