判断推理のテストの得点差の問題をPythonで解いてみた。

 知恵袋で見つけた判断推理のテストの得点差の問題Pythonで解いてみました。(^_^;

 A~Eの5人が100点満点のテストを受けた。その結果は、(ア)AとBは30点差、(イ)BとCは35点差、(ウ)CとDは15点差、(エ)DとEは30点差、(オ)EとAは20点差であった。
 このとき有り得ないものはどれか?
(1)Aが5位 (2)Bが1位 (3)Cが2位 (4)Dが4位 (5)Eが3位

 ただし、得点差の条件に(ア)~(オ)の名前を、選択肢に(1)~(5)の番号を付ける等、問題文を少し修正しておきました。(^_^;
 拙ブログの記事「判断推理の身長差の問題をJavaで解いてみた。」を参考にしました。

● PointDiff1.py

# coding: UTF-8
# PointDiff1.py

from time import time
import itertools

# 確実にいえる選択肢を1つ得る
def getAns(choices):
    fmt = '%s' if choices.count(True)==1 else 'Error! {%s}'
    lst = [str(i+1) for i in range(len(choices)) if choices[i]]
    return fmt%','.join(lst)

# a[]の中で n 番目に大きな数値を取得する
def Large(a,n):
    m = len(a)
    b = sorted(a)
    if(n< 1 or m< n): n=1   # n が範囲外の時は、n=1
    return b[m-n]

# a[]に先頭からA~Eと名前をつけて、n 番目に大きいものの名前を取得する
def getNameOfLarge(a,n):
    NAME = "ABCDE"
    return NAME[a.index(Large(a,n))]

# a[]に先頭からA~Eと名前をつけて、大きい順に名前を並べた文字列を返す
def getRanking(a):
    n = len(a)
    s = ''
    for i in range(n):
        s+=getNameOfLarge(a,i+1)
    return s

def main():
    tm = time() # Timer Start
    choices = [True]*5
    AB,BC,CD,DE,EA = 30,35,15,30,20     # 得点差
    cnt = 0
    a = 0   # aを0として、b~eの相対値を調べる。
    for b in (a-AB,a+AB):                       # 条件ア
        for c in (b-BC,b+BC):                   # 条件イ
            for d in (c-CD,c+CD):               # 条件ウ
                for e in (d-DE,d+DE):           # 条件エ
                    if abs(a-e)!=EA: continue   # 条件オ
                    n = (a,b,c,d,e)
                    pass # チェックを潜り抜けたものだけを表示
                    cnt+=1
                    print('[%d] %s : %s'%\
                        (cnt,getRanking(n),sorted(n,reverse=True)))
                    pass # 選択肢のチェック
                    choices[0] &= (getNameOfLarge(n,5)!='A')
                    choices[1] &= (getNameOfLarge(n,1)!='B')
                    choices[2] &= (getNameOfLarge(n,2)!='C')
                    choices[3] &= (getNameOfLarge(n,4)!='D')
                    choices[4] &= (getNameOfLarge(n,3)!='E')

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

if __name__ == '__main__':
    main()

●実行結果

[1] AEBDC : [0, -20, -30, -50, -65]
[2] ECADB : [20, 5, 0, -10, -30]
[3] BDACE : [30, 10, 0, -5, -20]
[4] CDBEA : [65, 50, 30, 20, 0]
∴5
Runtime : 0.000 [sec]

※参考URL
判断推理の身長差の問題をJavaで解いてみた。 - rscのブログ