知恵袋で見つけた判断推理のリーグ戦の問題をPythonで解いてみた。

 知恵袋で見つけた判断推理のリーグ戦の問題Pythonで解いてみました。

 A〜Eの5チームが総当たりのリーグ戦でサッカーの試合を行った結果、次のア〜カのことがわかっているとき、確実にいえることとして、最も妥当なのはどれか。
ア AはBに勝った。
イ BはCと引き分けた。
ウ CはAに負けた。
エ DはCに勝った。
オ EはDと引き分けた。
カ 5チームのうち、4チームの勝敗数が同じであった。
選択肢
1 AはDと引き分けた。
2 BはDに負けた。
3 CはEに負けた。
4 DはBと引き分けた。
5 EはAに負けた。

 勝ち点p[i]を勝ち100点、引分け10点、負け1点とすると、表中の反対称な得点q[i]は100/p[i]で表すことができます。また、合計点の百の位が勝ち数、十の位が引分け数、一の位が負け数になります。
 空欄を変数p[i],q[i](ただし、i=0〜4)でおいて、条件を表であらわすと次のようになります。
 それから、扱いやすいように表の1行をそれぞれリストla〜leにしました。(^_^;

+------+------+------+------+------+------+
|      |  A  |  B  |  C  |  D  |  E  |(相手)
+------+------+------+------+------+------+
|  A  |  \  |  〇  |  〇  | p[0] | p[1] |
+------+------+------+------+------+------+
|  B  |  X  |  \  |  △  | p[2] | p[3] |
+------+------+------+------+------+------+
|  C  |  X  |  △  |  \  |  X  | p[4] |
+------+------+------+------+------+------+
|  D  | q[0] | q[2] |  〇  |  \  |  △  |
+------+------+------+------+------+------+
|  E  | q[1] | q[3] | q[4] |  △  |  \  |
+------+------+------+------+------+------+
※〇:勝(100); △:分(10); X:敗(1)

 条件[カ]をどう表すかでちょっと苦労しました。(^_^;

● LeagueSoccer.py

# coding: UTF-8
# LeagueSoccer.py

import itertools
from time import time

def PrintResult(lst):
    n = len(lst)
    S = u' ABCDE'
    print(S)
    for i in range(n):
        s = S[i+1]
        for j in range(n):
            k = lst[i][j]
            if   k==100: s+=u'〇'    # 勝:100
            elif k== 10: s+=u'△'    # 分: 10
            elif k==  1: s+=u'X'    # 敗:  1
            else:        s+=u'\'
        print(s)

def main():
    tm = time()  # Timer Start
    NAME = 'ABCDE'
    N = 5
    ch = [True]*5
    cnt = 0
    for p in itertools.product([100,10,1],repeat=N):    # 勝:100; 分:10; 敗:1
        q  = [100//p[i] for i in range(N)]  # 反対称な得点
        la = [  0 ,100 ,100 ,p[0],p[1]]     # 条件ア,ウ
        lb = [  1 ,  0 , 10 ,p[2],p[3]]     # 条件ア,イ
        lc = [  1 , 10 ,  0 ,  1 ,p[4]]     # 条件イ,ウ,エ
        ld = [q[0],q[2],100 ,  0 , 10 ]     # 条件エ,オ
        le = [q[1],q[3],q[4], 10 ,  0 ]     # 条件オ
        ls = [sum(la),sum(lb),sum(lc),sum(ld),sum(le)]
        if ls.count(sum(la))!=4 and ls.count(sum(lb))!=4: continue  # 条件カ
        # チェックを潜り抜けたものだけを表示
        cnt+=1
        print("[%d]"%cnt)
        PrintResult([la,lb,lc,ld,le])
        # 選択肢のチェック
        ch[0] &= (la[NAME.index('D')]==10)
        ch[1] &= (lb[NAME.index('D')]== 1)
        ch[2] &= (lc[NAME.index('E')]== 1)
        ch[3] &= (ld[NAME.index('B')]==10)
        ch[4] &= (le[NAME.index('A')]== 1)

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

if __name__ == '__main__':
    main()

●実行結果

[1]
 ABCDE
A\〇〇〇〇
BX\△〇X
CX△\X〇
DXX〇\△
EX〇X△\
∴ 5
Runtime : 0.000 [sec]

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