数学とプログラミングに弱い学生が論理パズルをPythonで解きたい話
これ楽しい
最近バイトでプログラム書いてない
この問題をプログラミングで解こう!
てなわけで1問だけ挑戦する.
4人の被告 A,B,C,Dが関与していて次の事実が明らかになった.
- (1) AとBが有罪ともに有罪なら,Cは共犯者だ.
- (2) Aが有罪ならば,BかCの少なくとも一人が共犯者だ.
- (3) Cが有罪ならば,Dは共犯者だ.
- (4) Aが潔白ならば,Dは有罪だ.
確実に有罪なのは誰で,有罪かどうかを決められないのは誰か.
なるほど,さっぱりわからん.
とりあえず,考えてみると(1)~(4)の条件を回して矛盾が発生した場合の時そのパターンを取り除くみたいな感じが良さそう.
てなわけでソースコードを考える.
(1) AとBが有罪ともに有罪なら,Cは共犯者だ.
AとBが有罪なら,Cも有罪らしい. つまり,
if A.isGuilty && B.isGuilty: C.isGuilty = True
うーんなんかおかしい.これ矛盾が発生したときじゃなくて条件を満たしたときだよね.
こう直したほうが良さそう.
def jugge1(*args,**args) if A.isGuilty && B.isGuilty: if not C.isGuilty: break
これなら無視できそう.
以下(2)~(4)を同様の手順で考えると,
(2) Aが有罪ならば,BかCの少なくとも一人が共犯者だ.
def jugge2(*args,**args) if A.isGuilty: if not C.isGuilty or B.isGuilty: break
(3) Cが有罪ならば,Dは共犯者だ.
def jugge3(*args,**args) if C.isGuilty: if not D.isGuilty: break
(4) Aが潔白ならば,Dは有罪だ.
def jugge4(*args,**args) if not A.isGuilty: if not D.isGuilty: break
レッツコーディング
<被告>.isGuiltyって書いたけど普通に2進数でやったほうが早そう.
def jugge1(a,b,c): if a == 1 and b == 1: if c == 0: return True def judge2(a,b,c): if a == 1: if b == 0 or c == 0: return True def judge3(c,d): if c == 1: if d == 0: return True def judge4(a,d): if a == 0: if d == 0: return True ans = [] for i in range(16): beIgonored = [] #この中にTrueが無ければセーフ binary = "{0:0>4}".format(bin(i)).replace("b","0") #0000が 0b0ってなるのを変えてる binary = list(binary) while len(binary) < 4: binary.insert(0,"0") #0000が 0b0ってなるのを変えてる while len(binary) > 4: binary.pop(0) a,b,c,d = int(binary[-1]),int(binary[-2]),int(binary[-3]),int(binary[-4]) beIgonored.append(jugge1(a,b,c)) beIgonored.append(judge2(a,b,c)) beIgonored.append(judge3(c,d)) beIgonored.append(judge4(a,d)) if not True in beIgonored: ans.append("".join(binary)) print(" _______________") print("| D | C | B | A |") print(" ───────────────") for a in ans: print("| {} | {} | {} | {} |".format(a[0],a[1],a[2],a[3],)) print(" ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾")
クソコードすぎて辛いな??????????
結果
D | C | B | A |
---|---|---|---|
1 | 0 | 0 | 0 |
1 | 0 | 1 | 0 |
1 | 1 | 0 | 0 |
1 | 1 | 1 | 0 |
1 | 1 | 1 | 1 |
真理値表
A~Dの中で有罪を1,潔白を0とする.
Zは矛盾が生じてない時に1,生じている時を0とする.
Mは条件(1)~(4)の中で条件を満たしたもの.
Nは条件(1)~(4)の中で矛盾が起きたものとする.
D | C | B | A | Z | M | N |
---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | ✖️ | (4) |
0 | 0 | 0 | 1 | 0 | ✖️ | (2) |
0 | 0 | 1 | 0 | 0 | ✖️ | (4) |
0 | 0 | 1 | 1 | 0 | (2) | (1) |
0 | 1 | 0 | 0 | 0 | ✖️ | (3),(4) |
0 | 1 | 0 | 1 | 0 | (2) | (3) |
0 | 1 | 1 | 0 | 0 | ✖️ | (3) |
0 | 1 | 1 | 1 | 0 | (1),(2) | (3) |
1 | 0 | 0 | 0 | 1 | (4) | ✖️ |
1 | 0 | 0 | 1 | 0 | ✖️ | (2) |
1 | 0 | 1 | 0 | 1 | (4) | ✖️ |
1 | 0 | 1 | 1 | 0 | (1) | (2) |
1 | 1 | 0 | 0 | 1 | (3),(4) | ✖️ |
1 | 1 | 0 | 1 | 0 | (2),(3) | (1) |
1 | 1 | 1 | 0 | 1 | (3),(4) | ✖️ |
1 | 1 | 1 | 1 | 1 | (1),(2),(3) | ✖️ |
あっなんかあってそう
つまり確実に有罪なのはDっぽい
コード書くより真理値表書くのが一番早いぞ!!!!!
クソコード書くの楽しかったおやすみなさい.