知恵袋で見つけた判断推理のミカンを分配する問題をPythonで解いてみた。

 知恵袋で見つけた判断推理のミカンを分配する問題Pythonで解いてみました。(^_^;

 A〜Eの5人が、35個のミカンを順に取って行った。以下ア〜オの条件に従って取ったとき、確実にいえるのはどれか。
ア、Eが最初に取った
イ、Dは最後に、残ったミカンをすべて取った
ウ、AとBはそれぞれ、残っているミカンのちょうど半分の個数を取った
エ、Cは残っているミカンの3分の2の個数を取った
オ、取ったミカンの個数は全員異なっていた

(1)Aは2番で取った
(2)Bは8個取った
(3)Cは4番で取った
(4)Dは2個取った
(5)Eは6個取った

※参考URL
http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1148054911

 A〜Eが取ったミカンの個数をa〜e[個]、残りの個数をr[個]としました。
 自力で解く場合は、余りに着目して、次式の{ }内が交換法則が成り立つことから、
 d=(35-e)*{(1/2)*(1/2)*(1/3)}=(35-e)/12
これが、整数になるように、(d,e)を決めて、後は、A,Bの条件の対称性を利用して、Cが何番目に来るかで場合分けです。

+-----+-----+-----+-----+-----+
|  E  |  C  |  A  |  B  |  D  |
+-----+-----+-----+-----+-----+
|  e  |2r/3 | r/6 | r/12| r/12|←B,Dが同じになるのでダメ
+-----+-----+-----+-----+-----+
|  r  | r/3 | r/6 | r/12|  0  | 残り:r=35-e
+-----+-----+-----+-----+-----+
+-----+-----+-----+-----+-----+
|  E  |  A  |  C  |  B  |  D  |
+-----+-----+-----+-----+-----+
|  e  | r/2 | r/3 | r/12| r/12|←同様にダメ
+-----+-----+-----+-----+-----+
|  r  | r/2 | r/6 | r/12|  0  | 残り
+-----+-----+-----+-----+-----+
+-----+-----+-----+-----+-----+
|  E  |  A  |  B  |  C  |  D  |←A,Bは交換可
+-----+-----+-----+-----+-----+
|  e  | r/2 | r/4 | r/6 | r/12|
+-----+-----+-----+-----+-----+
|  r  | r/2 | r/4 | r/12|  0  | 残り
+-----+-----+-----+-----+-----+

 これから、Cは4番目に来ることがわかるようです。(^_^;

● MandarinOrange.py

# coding: UTF-8
# MandarinOrange.py

def main():
    import itertools
    from time import time

    tm = time()  # Timer Start
    choices = [True]*5
    P = 'abc'
    cnt = 0
    for p in itertools.permutations(P):
        s = 'e'+''.join(p)+'d'                              # 条件アイ
        for e in range(35):                                 # 条件ア
            # 1番目
            r = 35-e    # 残り
            # 2番目〜4番目
            for i in range(3):
                if p[i]=='c':
                    if r%3!=0: break
                    c = r*2//3; r-=c                        # 条件エ
                else:
                    if r%2!=0: break
                    r//=2
                    exec('%s = %s'%(p[i],r),globals())      # 条件ウ
            else: i+=1
            if i< 3: continue
            # 5番目
            d = r                                           # 条件イ
            if r<=0: continue
            if len(set([a,b,c,d,e]))!=5: continue           # 条件オ
            # チェックを潜り抜けたものだけを表示
            cnt+=1
            print("[%d] %s"%(cnt,s.upper()))
            t = ""
            for i in range(5):
                t+="%d "%(eval(s[i]))
            print("%s"%t[:-1])
            # 選択肢のチェック
            choices[0] &= (s.index('a')+1==2)
            choices[1] &= (b==8)
            choices[2] &= (s.index('c')+1==4)
            choices[3] &= (d==2)
            choices[4] &= (e==6)

    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] EABCD
11 12 6 4 2
[2] EABCD
23 6 3 2 1
[3] EBACD
11 12 6 4 2
[4] EBACD
23 6 3 2 1
∴ 3
Runtime : 0.015 [sec]