判断推理の履修状況の問題をPythonで解いてみた。

 判断推理の履修状況の対応関係の問題Pythonで解いてみました。

 A~Eの学生5人における政治学、経済学、行政学社会学法律学の5科目の履修状況について次のことがわかているとき、確実にいえるのはどれか。
(ア)5人が履修している科目数はそれぞれ3科目以内である。
(イ)政治学を履修している者は2人いる。
(ウ)経済学を履修している者は2人おり、そのうちの1人はAである。
(エ)行政学を履修している者は3人おり、そのうちの1人はAである。
(オ)社会学を履修している者は3人おり、そのうちの2人はAとDである。
(カ)法律学を履修している者は4人いる。
(キ)AとEが2人とも履修している科目はない。
(ク)Cは政治学社会学も履修していない。
選択肢
1. Bは政治学を履修していない。
2. Bは行政学を履修していない。
3. Cは経済学を履修していない。
4. Dは経済学を履修していない。
5. Dは行政学を履修していない。

 ただし、条件に(ア)~(ク)の名前を付けました。
 政治学をp、経済学をq、行政学をr、社会学をs、法律学をtとして、組合せで回してみました。(^_^;
 A~E各人の履修表は、政治学から順に、履修したら1、履修していないなら0としてリストを作成しました。
 条件(キ)は、「(1,1) in zip(a,e)」で調べました。list(zip())は、tupleのlistになっていました。

● Courses1.py

# coding: UTF-8
# Courses1.py

import itertools
from time import time

# 確実にいえる選択肢を得る
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 = 'ABCDE'
    # p:政治学、q:経済学、r:行政学、s:社会学、t:法律学
    for p in itertools.combinations(P,2):                   # 条件(イ)
        if 'C' in p: continue                               # 条件(ク)
        for q in itertools.combinations(P,2):               # 条件(ウ)
            if not 'A' in q: continue                       # 条件(ウ)
            for r in itertools.combinations(P,3):           # 条件(エ)
                if not 'A' in r: continue                   # 条件(エ)
                for s in itertools.combinations(P,3):       # 条件(オ)
                    if not 'A' in s: continue               # 条件(オ)
                    if not 'D' in s: continue               # 条件(オ)
                    if     'C' in s: continue               # 条件(ク)
                    for t in itertools.combinations(P,4):   # 条件(カ)
                        # 各人の履修表を作成
                        a = [int('A' in x) for x in (p,q,r,s,t)]
                        b = [int('B' in x) for x in (p,q,r,s,t)]
                        c = [int('C' in x) for x in (p,q,r,s,t)]
                        d = [int('D' in x) for x in (p,q,r,s,t)]
                        e = [int('E' in x) for x in (p,q,r,s,t)]
                        if not sum(a)<=3: continue          # 条件(ア)
                        if not sum(b)<=3: continue          # 条件(ア)
                        if not sum(c)<=3: continue          # 条件(ア)
                        if not sum(d)<=3: continue          # 条件(ア)
                        if not sum(e)<=3: continue          # 条件(ア)
                        if (1,1) in zip(a,e): continue      # 条件(キ)
                        pass # チェックを潜り抜けたものを表示
                        print('政:%s'%toStr(p,''),end=', ')
                        print('経:%s'%toStr(q,''),end=', ')
                        print('行:%s'%toStr(r,''),end=', ')
                        print('社:%s'%toStr(s,''),end=', ')
                        print('法:%s'%toStr(t,''))
                        pass # 選択肢のチェック
                        choices[0] &= ('B' not in p)
                        choices[1] &= ('B' not in r)
                        choices[2] &= ('C' not in q)
                        choices[3] &= ('D' not in q)
                        choices[4] &= ('D' not in r)

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

if __name__ == '__main__':
    main()

●実行結果

政:BE, 経:AC, 行:ACD, 社:ABD, 法:BCDE
政:DE, 経:AC, 行:ABC, 社:ABD, 法:BCDE
∴4
Runtime : 0.031 [sec]

※参考URL
知恵袋で見つけた判断推理の出勤簿の問題をPythonで解いてみた。 - rscのブログ
知恵袋で見つけた判断推理の出勤簿の問題をPythonで解いてみた。(2) - rscのブログ