知恵袋で見つけた判断推理のトーナメントの問題をPythonで解いてみました。(^_^;
ある大学のテニス大会で、AからGの7チームが、下図のようなトーナメント戦を行ったところ、次のア〜オのことが分かった。
ア Aは1回だけ勝ち、Bには負けた。
イ Cは初戦でGに敗退した。
ウ AとDは、ともにEとは対戦しなかった。
エ Dは2回戦で敗退した。
オ Gは2回勝ち、決勝戦で敗退した。
以上から判断して、確実にいえるのはどれか。1.Aは1回戦でFと戦った。
2.BはFに勝った。
3.Cは2回戦からの登場だった。
4.Dは2回戦でBと戦った。
5.GはEに勝った。
下図のようなトーナメント戦のそれぞれの位置に入るチーム名を、K,L,M,N,Q,R,S,X,Y,Z,U,V,Wとおいて、対称性からK<L, M<N, Q<R, K<Mと順序を与えることにします。
W +-----+-----+ 3回戦 | | U V +--+--+ +--+--+ 2回戦 | | | | X Y Z S +-+-+ +-+-+ +-+-+ | 1回戦 | | | | | | | K < L M < N Q < R S K < M
● TournamentTennis.py
# coding: UTF-8 # TournamentTennis.py import itertools from time import time # cが何回戦まで出場したかを対戦データlstから求める def getRound(c, lst): if c not in lst: return 1 n = lst.index(c)+1 if n< 2: return 4 elif n< 4: return 3 else: return 2 # aとbの対戦が対戦リストlst内にあるか調べる def hasMatched(a, b, lst): if [a,b] in lst: return True if [b,a] in lst: return True return False # aがbと対戦して勝ったかを対戦データlstから調べる def hasWon(a, b, lst): if [a,b,a] in lst: return True if [b,a,a] in lst: return True return False # 次元を下げる def flatten(lst): return list(itertools.chain.from_iterable(lst)) def main(): tm = time() # Timer Start ch = [True]*5 #1234567 P = 'ABCDEFG' cnt = 0 for p in itertools.permutations(P): k,l,m,n,q,r,s = p if k>=l or m>=n or k>=m or q>=r: continue lFst = [[k,l],[m,n],[q,r]] for b in itertools.product([True,False],repeat=6): x,y,z = k if b[0] else l, m if b[1] else n, q if b[2] else r u,v = x if b[3] else y, z if b[4] else s w = u if b[5] else v lSnd = [[x,y],[z,s]] lTrd = [[u,v]] lAll = lFst+lSnd+lTrd lgRd = [w]+flatten(lTrd+lSnd) # getRound用データ lWin = lgRd[:-1] # 勝者のリスト[w,u,v,x,y,z] lhWn = [[k,l,x],[m,n,y],[q,r,z],[x,y,u],[z,s,v],[u,v,w]] # hasWon用 if lWin.count('A')!=1: continue # 条件ア if not hasWon('B','A',lhWn): continue # 条件ア if lWin.count('C')!=0: continue # 条件イ if not hasWon('G','C',lhWn): continue # 条件イ if hasMatched('A','E',lAll): continue # 条件ウ if hasMatched('D','E',lAll): continue # 条件ウ if getRound('D',lgRd)!= 2: continue # 条件エ if lWin.count('G')!=2: continue # 条件オ if w=='G': continue # 条件オ # チェックを潜り抜けたものだけを表示 cnt+=1 print("[%2d] %c "%(cnt,w)) print(" +-----+-----+ ") print(" | | ") print(" %c %c "%(u,v)) print(" +--+--+ +--+--+") print(" | | | |") print(" %c %c %c %c"%(x,y,z,s)) print(" +-+-+ +-+-+ +-+-+ |") print(" | | | | | | |") print(" %c %c %c %c %c %c %c"%(k,l,m,n,q,r,s)) print("") # 選択肢のチェック ch[0] &= hasMatched('A','F',lFst) ch[1] &= hasWon ('B','F',lhWn) ch[2] &= (s=='C') ch[3] &= hasMatched('B','D',lSnd) ch[4] &= hasWon ('G','E',lhWn) 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] B +-----+-----+ | | B G +--+--+ +--+--+ | | | | A B G D +-+-+ +-+-+ +-+-+ | | | | | | | | A F B E C G D ∴ 1 Runtime : 0.275 [sec]
※参考URL
http://stackoverflow.com/questions/103844/how-do-i-merge-a-2d-array-in-python-into-one-string-with-list-comprehension
●Pythonでリストをflattenする方法まとめ - Soleil cou coupe
●知恵袋で見つけた判断推理のトーナメントの問題をPythonで解いてみた。
●知恵袋で見つけた判断推理のトーナメントの問題をPythonで解いてみた。(3)
- 作者: 辻真吾
- 出版社/メーカー: 技術評論社
- 発売日: 2010/04/24
- メディア: 大型本
- 購入: 19人 クリック: 199回
- この商品を含むブログ (59件) を見る
パーフェクトPython (PERFECT SERIES 5)
- 作者: Pythonサポーターズ,露木誠,ルイス・イアン,石本敦夫,小田切篤,保坂翔馬,大谷弘喜
- 出版社/メーカー: 技術評論社
- 発売日: 2013/03/05
- メディア: 大型本
- 購入: 1人 クリック: 65回
- この商品を含むブログ (30件) を見る