知恵袋の判断推理の論理問題をPythonで解いてみました。(^_^;
ある集団について調査をしたところ、次のA〜Dのことがわかった。ここから確実に言えるのは1〜5のうちどれか
A:数学が得意な人は英語が好きである。
B:音楽が好きな人は社会も数学も得意である。
C:社会が得意でない人は美術が好きである。
D:英語が好きな人や美術が好きでない人は国語が得意である1.数学が得意な人は社会が得意である
2.国語が得意でない人は社会が得意でない
3.美術が好きな人は英語が好きである
4.音楽が好きな人は国語が得意である
5.英語が好きでない人は美術が好きである
「数学が得意である」をm、「英語が好きである」をe、「音楽が好きである」をo、「社会が得意である」をs、「美術が好きである」をa、「国語が得意である」をjと置きました。
論理包含「A⇒B」の真理値を得るImp(a,b)関数は、1番目の参考URLを参考にして作りました。
ちなみに、not Imp(a,b) = not((not a) or b) = a and (not b)。
● Logic1.py
# coding: UTF-8 # Logic1.py import itertools from time import time # 論理包含「A⇒B」の真理値を得る def Imp(a,b): return not a or b # 真理値表の1行を文字列で得る def getRowOfTruthTable(lst): result = "" for b in lst: result += " T" if b else " F" return result def main(): tm=time() # Timer Start print("[m,e,o,s,a,j]") # m:数学; e:英語; o:音楽; s:社会; a:美術; j:国語 choices = [True]*5 for m,e,o,s,a,j in itertools.product([True,False],repeat=6): if not Imp( m, e): continue # 条件A if not Imp( o,s and m): continue # 条件B if not Imp( not s, a): continue # 条件C if not Imp(e or not a, j): continue # 条件D # チェックを潜り抜けたものだけを表示 print(getRowOfTruthTable([m,e,o,s,a,j])) # 選択肢のチェック choices[0] &= Imp( m, s) choices[1] &= Imp(not j,not s) choices[2] &= Imp(not a, e) choices[3] &= Imp( o, j) choices[4] &= Imp(not e, a) 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()
●実行結果
[m,e,o,s,a,j] T T T T T T T T T T F T T T F T T T T T F T F T T T F F T T F T F T T T F T F T F T F T F F T T F F F T T T F F F T T F F F F T F T F F F F T T F F F F T F ∴ 4 Runtime : 0.000 [sec]
P.S.
条件を満たす場合の真理値表の横に選択肢の真理値表も付けると、次のようになります。
● Logic1a.py
# coding: UTF-8 # Logic1a.py import itertools from time import time # 論理包含「A⇒B」の真理値を得る def Imp(a,b): return not a or b # 真理値表の1行を文字列で得る def getRowOfTruthTable(li): return ' '.join(['T' if b else 'F' for b in li]) # 確実にいえる選択肢を1つ得る def getAns(choices): if choices.count(True)!=1: print('Error!') return ','.join([str(i+1) for i in range(5) if choices[i]]) # Cのように1行で値を代入して比較するため def let(li,elem): li.append(elem) return elem def main(): tm = time() # Timer Start choices = [True]*5 TF = (True,False) # m:数学; e:英語; o:音楽; s:社会; a:美術; j:国語 print("[m,e,o,s,a,j] 1 2 3 4 5") for m,e,o,s,a,j in itertools.product(TF,repeat=6): if not Imp( m, e): continue # 条件A if not Imp( o,s and m): continue # 条件B if not Imp( not s, a): continue # 条件C if not Imp(e or not a, j): continue # 条件D pass # チェックを潜り抜けたものだけを表示 s1 = getRowOfTruthTable([m,e,o,s,a,j]) pass # 選択肢のチェック c = [] choices[0] &= let(c, Imp( m, s)) choices[1] &= let(c, Imp(not j,not s)) choices[2] &= let(c, Imp(not a, e)) choices[3] &= let(c, Imp( o, j)) choices[4] &= let(c, Imp(not e, a)) s2 = getRowOfTruthTable(c) print(' %s %s'%(s1,s2)) print(u"∴%s"%getAns(choices)) print("Runtime : %.3f [sec]"%(time()-tm)) # Timer Stop & Disp if __name__ == '__main__': main()
●実行結果
[m,e,o,s,a,j] 1 2 3 4 5 T T T T T T T T T T T T T T T F T T T T T T T T F T T T T T T T T T T F T F T T T T T T T T F F T T F T T T T F T F T T T T T T T T F T F T F T T T T T T F T F F T T T T T T T F F F T T T T T T T T F F F T T F T F T T T F F F T F T T T F T F F F F F T T T T T T T F F F F T F T T T T T ∴4 Runtime : 0.000 [sec]
※参考URL
●@IT:連載:プロフェッショナルVB.NETプログラミング 第6回 論理演算と制御構造
●論理包含 ‐ 通信用語の基礎知識
●知恵袋の判断推理の論理問題をPythonで解いてみた。(2)
●知恵袋の判断推理の論理問題をJavaで解いてみた。