知恵袋で見つけた判断推理のトランプの問題をPythonで解いてみました。(^_^;
トランプの4種類のマークのカードがそれぞれ5枚(うち1枚はエース)、計20枚ある。
これをA,B,C,Dの4人に5枚ずつ配ったところ、それぞれ次のように話した。
A 『同じ種類が4枚ある。エースが2枚ある』
B 『ダイヤが3枚、スペードが1枚、他のマークが1枚ある』
C 『ダイヤが1枚、クラブが3枚ある』
D 『すべての種類のカードがある。エースが1枚ある』
このとき、次のア~ウのうち、常に正しいといえるものの組み合わせはどれか。
ア、ハートを持っている者は、スペードを持っている。
イ、スペードを持っている者は、ダイヤを持っている。
ウ、クラブを持っている者は、ダイヤを持っている。
ただし、P,Q,R,XをA,B,C,Dに変えました。また、問題では、エースのことしか触れられていませんが、他は任意ということで番号をK,A,2,3,4と自分で設定しました。
以前に作った拙プログラムTrump1.pyを雛形にしましたが、ちょっと改良しました。
問題は、選択肢が大きく変わっていますが、条件部分はあまり変わっていないようです。選択肢の判定には、論理包含Impとall関数を使ってみました。(^_^;
● Trump2.py
# coding: UTF-8 # Trump2.py import itertools from time import time SUIT = 'SDCH' RANK = 'KA234' N = len(RANK) # 1人分の枚数 # sRank: 'K','A','2','3','4' def countRank(sRank, cards): n = RANK.index(sRank) count = 0 for c in cards: if c%N==n: count+=1 return count # sSuit: 'S','D','C','H' def countSuit(sSuit, cards): n = SUIT.index(sSuit) count = 0 for c in cards: if c//N==n: count+=1 return count 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 "(" + ','.join(li) + ")" # 論理包含Imp def Imp(p,q): return not p or q # 確実にいえる選択肢を得る 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]*3 Cards = range(4*N) for a in itertools.combinations(Cards,N): if not 4 in countSuits(a): continue # 条件A-1 if countRank('A',a)!=2: continue # 条件A-2 B = tuple(set(Cards)-set(a)) # aを除いた残り for b in itertools.combinations(B,N): if countSuit('D',b)!=3: continue # 条件B-1 if countSuit('S',b)!=1: continue # 条件B-2 C = tuple(set(B)-set(b)) # a,bを除いた残り for c in itertools.combinations(C,N): if countSuit('D',c)!=1: continue # 条件C-1 if countSuit('C',c)!=3: continue # 条件C-2 d = tuple(set(C)-set(c)) # a,b,cを除いた残り if 0 in countSuits(d) : continue # 条件D-1 if countRank('A',d)!=1: continue # 条件D-2 # チェックを潜り抜けたものを表示 ## print(toStrCards(a),toStrCards(b),toStrCards(c),toStrCards(d)) # 選択肢のチェック li = [a,b,c,d] choices[0] &= all([Imp(countSuit('H',x)!=0,countSuit('S',x)!=0) for x in li]) choices[1] &= all([Imp(countSuit('S',x)!=0,countSuit('D',x)!=0) for x in li]) choices[2] &= all([Imp(countSuit('C',x)!=0,countSuit('D',x)!=0) for x in li]) print(u"∴%s"%getAns(choices,'アイウ')) print("Runtime : %.3f [sec]"%(time()-tm)) # Timer Stop & Disp if __name__ == '__main__': main()
●実行結果
∴ア,ウ Runtime : 6.953 [sec]
※参考URL
●組み込み関数 — Python 3.9.0 ドキュメント
●知恵袋で見つけた判断推理のトランプの問題をPythonで解いてみた。 - rscのブログ
●知恵袋で見つけた判断推理のトランプの問題をPythonで解いてみた。(3) - rscのブログ