数学とプログラミングに弱い学生が論理パズルを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っぽい
コード書くより真理値表書くのが一番早いぞ!!!!!
クソコード書くの楽しかったおやすみなさい.
