知恵袋で見つけた判断推理のカードの問題をPythonで解いてみました。(^_^;
カードの表・裏2つの面を、赤、黒、青、黄のいずれかの色で塗ったカードが8枚ある。赤は5面、黒は3面、青、黄はそれぞれ4面ずつである。両面が同じ色のカードは1枚もない。
いま、8枚のカードを並べたところ、4枚は赤、3枚は黒、1枚は黄色であった。このうち4枚のカードを裏返したところ、赤は2枚、黒は1枚、青は4枚、黄は1枚になった。以上のことから、カードの表・裏2つの面について、正しいものはどれか。①黄・青のカードは全部で2枚ある。
②赤・青のカードは全部で2枚ある。
③赤・黄のカードは1枚もない。
④黒・黄のカードは全部で2枚ある。
⑤黒のカードの他の面の色は全て異なる。
ただし、問題文が一部抜けているようなので補っておきました。(^_^;
赤、黒、青、黄の色をそれぞれ、'r','k','b','y'として、「いま、…」以下の条件に出てくる仮の表・裏の色の並びを文字列F,Bとしました。F,Bの決め方は以下の通りです。(^_^;
+----+----+----+----+----+ | | 赤 | 黒 | 青 | 黄 | +----+----+----+----+----+ | 全 | 5 | 3 | 4 | 4 | → |rrrrr|kkk|bbbb|yyyy| → A = 'rrrrrkkkbbbbyyyy' +----+----+----+----+----+ | 表 | 4 | 3 | 0 | 1 | → |rrrr |kkk| |y | → F = 'rrrrkkky' +----+----+----+----+----+ | 裏 | 1 | 0 | 4 | 3 | → | r| |bbbb| yyy| → B = 'rbbbbyyy' +----+----+----+----+----+
仮の表を固定して、裏の色を同じものを含む順列で回して、裏返す4枚のカードの位置を組合せで回してみました。(^_^;
選択肢をチェックするために、表と裏のそれぞれの色のタプルtF,tBからカードの両面2色のリストのリストを作成して、その中で、sTargetが両面の色を表した2文字となるカードの枚数を求める関数countCard(sTarget,tF,tB)を作りました。
ちなみに、「黒のカードの他の面の色は全て異なる。」ということは、「{黒・赤},{黒・青},{黒・黄}のカードが1枚ずつある」ってことですよね。(^_^;
P.S.
両面が同色のカードは1枚もない条件「flg = False~if flg: continue」は、any()関数を使うと、次の1行に書き換えることができます。o(^-^)o
if any([f[i]==b[i] for i in range(N)]): continue
● Cards1.py
# coding: UTF-8 # Cards1.py from time import time import itertools # 表と裏のそれぞれの色のタプルtF,tBからカードの両面2色のリストのリストを作成して、 # その中で、sTargetが両面の色を表した2文字となるカードの枚数を求める def countCard(sTarget,tF,tB): li = [sorted(tF[i]+tB[i]) for i in range(len(tF))] return li.count(sorted(sTarget)) def main(): tm = time() # Timer Start ch = [False]*5 F = 'rrrrkkky' # 仮の表 B = 'rbbbbyyy' N = len(F) cnt = 0 f = tuple(F) print('[%2d] %s'%(0,list(f))) # 仮の表も参考までに表示 for b in set(itertools.permutations(B)): # 同じものを含む順列 flg = False for i in range(N): if f[i]==b[i]: flg = True if flg: break if flg: continue # 両面が同色のカードは1枚もない条件 for c in itertools.combinations(range(N),4): s = '' # 4枚のカードを裏返したときの色の状態 for i in range(N): if i in c: s+=b[i] else: s+=f[i] if sorted(s)!=sorted('rrkbbbby'): continue # チェックを潜り抜けたものだけを表示 cnt+=1 print('[%2d] %s'%(cnt,b)) # 選択肢のチェック if cnt==1: ch = [True]*5 ch[0] &= (countCard('yb',f,b)==2) ch[1] &= (countCard('rb',f,b)==2) ch[2] &= (countCard('ry',f,b)==0) ch[3] &= (countCard('ky',f,b)==2) pr = countCard('kb',f,b)*countCard('kr',f,b)*countCard('ky',f,b) ch[4] &= (pr==1) 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()
●実行結果
[ 0] ['r', 'r', 'r', 'r', 'k', 'k', 'k', 'y'] [ 1] ('y', 'b', 'b', 'y', 'b', 'b', 'y', 'r') [ 2] ('b', 'y', 'y', 'b', 'b', 'b', 'y', 'r') [ 3] ('y', 'y', 'b', 'b', 'b', 'b', 'y', 'r') [ 4] ('y', 'b', 'y', 'b', 'y', 'b', 'b', 'r') [ 5] ('b', 'y', 'y', 'b', 'b', 'y', 'b', 'r') [ 6] ('b', 'y', 'b', 'y', 'y', 'b', 'b', 'r') [ 7] ('b', 'b', 'y', 'y', 'y', 'b', 'b', 'r') [ 8] ('y', 'b', 'y', 'b', 'b', 'b', 'y', 'r') [ 9] ('b', 'y', 'b', 'y', 'b', 'b', 'y', 'r') [10] ('b', 'y', 'b', 'y', 'b', 'y', 'b', 'r') [11] ('y', 'b', 'b', 'y', 'b', 'y', 'b', 'r') [12] ('y', 'y', 'b', 'b', 'b', 'y', 'b', 'r') [13] ('y', 'b', 'y', 'b', 'b', 'y', 'b', 'r') [14] ('y', 'y', 'b', 'b', 'y', 'b', 'b', 'r') [15] ('y', 'b', 'b', 'y', 'y', 'b', 'b', 'r') [16] ('b', 'y', 'y', 'b', 'y', 'b', 'b', 'r') [17] ('b', 'b', 'y', 'y', 'b', 'b', 'y', 'r') [18] ('b', 'b', 'y', 'y', 'b', 'y', 'b', 'r') ∴ 2 Runtime : 0.078 [sec]
※参考URL
●判断推理のカードの問題をJavaで解いてみた。
判断推理がみるみるわかる! 解法の玉手箱 改訂第2版 (公務員試験)
- 発売日: 2016/08/26
- メディア: 単行本(ソフトカバー)
- 作者:鈴木 清士
- 発売日: 1999/11/01
- メディア: 単行本