知恵袋で見つけた判断推理のトランプの問題をPythonで解いてみました。(^_^;
トランプが12枚ある。ハート、ダイヤ、クラブ、スペードの4種類でそれぞれにジャック、クィーン、キングが揃っている。A~Dの4人に3枚ずつ配ったところ次のことが分かった。
・Aにはハートが2枚あるがクラブはない
・Bにはジャックが2枚あるがハートはない
・Cにはスペードとクイーンは2枚あるがキングはない
・Dにはダイヤが2枚とクラブのキングがある
以上のことから正しいものをえらびなさい
1 Aにはキングが2枚ある
2 Bにはダイヤのクイーンがある
3 Cにはハートのジャックがある
4 Dにはクイーンが2枚ある
5 Bにはスペードのキングがある
前回、作った拙プログラムTrump2.pyを雛形にしましたが、countRank関数とcountSuit関数をちょっと書き直してみました。(^_^;
トランプに、0~11の通し番号を与えて、1人分の枚数3で割った商でスート(絵柄マーク)、3で割った余りからランク(番号)を得ることにしました。
sSuit: ('S','D','C','H') = n: (0,1,2,3) = (スペード,ダイア,クラブ,ハート) sRank: ('J','Q','K') = n: (0,1,2) = (ジャック,クィーン,キング) 0 1 2 J Q K : Rank 0 S 0 1 2 1 D 3 4 5 2 C 6 7 8 3 H 9 10 11 Suit
● Trump3.py
# coding: UTF-8 # Trump3.py import itertools from time import time SUIT = 'SDCH' RANK = 'JQK' N = len(RANK) # 1人分の枚数 # sRank: 'J','Q','K' def countRank(sRank, cards): li = [] for c in cards: li.append(RANK[c%N]) return li.count(sRank) # sSuit: 'S','D','C','H' def countSuit(sSuit, cards): li = [] for c in cards: li.append(SUIT[c//N]) return li.count(sSuit) def countSuits(cards): return [countSuit(SUIT[i],cards) for i in range(4)] # suitとrankから通し番号を得る def getN(sSuit,sRank): return SUIT.index(sSuit)*N+RANK.index(sRank) def toStrCards(cards): li = [] for c in cards: li.append(SUIT[c//N]+RANK[c%N]) return "(%s)"%(','.join(li)) # 確実にいえる選択肢を得る def getAns(cho,lbl='12345'): return ','.join([lbl[i] for i in range(len(cho)) if cho[i]]) def main(): tm = time() # Timer Start choices = [True]*5 Cards = range(4*N) for a in itertools.combinations(Cards,N): if countSuit('H',a)!=2: continue # 条件A-1 if countSuit('C',a)!=0: continue # 条件A-2 B = tuple(set(Cards)-set(a)) # aを除いた残り for b in itertools.combinations(B,N): if countRank('J',b)!=2: continue # 条件B-1 if countSuit('H',b)!=0: continue # 条件B-2 C = tuple(set(B)-set(b)) # a,bを除いた残り for c in itertools.combinations(C,N): if countSuit('S',c)!=2: continue # 条件C-1 if countRank('Q',c)!=2: continue # 条件C-2 if countRank('K',c)!=0: continue # 条件C-3 d = tuple(set(C)-set(c)) # a,b,cを除いた残り if countSuit('D',d)!=2: continue # 条件D-1 if not getN('C','K') in d: continue # 条件D-2 # チェックを潜り抜けたものだけを表示 print(toStrCards(a),toStrCards(b),toStrCards(c),toStrCards(d)) # 選択肢のチェック choices[0] &= (countRank('K',a)==2) choices[1] &= (getN('D','Q') in b ) choices[2] &= (getN('H','J') in c ) choices[3] &= (countRank('Q',d)==2) choices[4] &= (getN('S','K') in b ) print(u"∴%s"%getAns(choices)) print("Runtime : %.3f [sec]"%(time()-tm)) # Timer Stop & Disp if __name__ == '__main__': main()
●実行結果
(SK,HJ,HK) (DJ,CJ,CQ) (SJ,SQ,HQ) (CK,DQ,DK) ∴1 Runtime : 0.016 [sec]
※参考URL
●知恵袋で見つけた判断推理のトランプの問題をPythonで解いてみた。 - rscのブログ
●知恵袋で見つけた判断推理のトランプの問題をPythonで解いてみた。(2) - rscのブログ