Skip to content

Instantly share code, notes, and snippets.

@tzengyuxio
Created May 30, 2019 16:39
Show Gist options
  • Save tzengyuxio/cf835dd056a84f955fb94d49f6438622 to your computer and use it in GitHub Desktop.
Save tzengyuxio/cf835dd056a84f955fb94d49f6438622 to your computer and use it in GitHub Desktop.
2018 年刑偵科推理試題
#!/usr/bin/env python3
# 題目: https://imgur.com/a/WvVHKUO
import string
base = 4
digs = string.digits + string.ascii_letters
N = 4 ** 10
def to_base4(n):
digits = []
while n:
digits.append(digs[int(n % base)])
n = int(n / base)
if len(digits) < 10:
digits += ['0'] * (10 - len(digits))
digits.reverse()
return digits
def base4_to_abcd(digits):
return [chr(65+int(x)) for x in digits]
def check_1(ans):
# 本題 always true
return True
def check_2(ans):
if (ans[1] == 'A' and ans[4] == 'C'):
return True
if (ans[1] == 'B' and ans[4] == 'D'):
return True
if (ans[1] == 'C' and ans[4] == 'A'):
return True
if (ans[1] == 'D' and ans[4] == 'B'):
return True
return False
def check_3(ans):
if (ans[2] == 'A'):
return (ans[5] != ans[2]) and (ans[5] == ans[1]) and (ans[5] == ans[3])
if (ans[2] == 'B'):
return (ans[2] != ans[5]) and (ans[2] == ans[1]) and (ans[2] == ans[3])
if (ans[2] == 'C'):
return (ans[2] != ans[1]) and (ans[2] == ans[5]) and (ans[2] == ans[3])
if (ans[2] == 'D'):
return (ans[2] != ans[3]) and (ans[2] == ans[5]) and (ans[5] == ans[1])
def check_4(ans):
# 未排除多選成立情況
if (ans[3] == 'A'):
return ans[0] == ans[4]
if (ans[3] == 'B'):
return ans[1] == ans[6]
if (ans[3] == 'C'):
return ans[0] == ans[8]
if (ans[3] == 'D'):
return ans[5] == ans[9]
def check_5(ans):
if (ans[4] == 'A'):
return (ans[7] == 'A' and ans[3] != 'A' and ans[8] != 'A' and ans[6] != 'A')
if (ans[4] == 'B'):
return (ans[7] != 'B' and ans[3] == 'B' and ans[8] != 'B' and ans[6] != 'B')
if (ans[4] == 'C'):
return (ans[7] != 'C' and ans[3] != 'C' and ans[8] == 'C' and ans[6] != 'C')
if (ans[4] == 'D'):
return (ans[7] != 'D' and ans[3] != 'D' and ans[8] != 'D' and ans[6] == 'D')
def check_6(ans):
# 未排除多選成立情況
if (ans[5] == 'A'):
return (ans[7] == ans[1] and ans[7] == ans[3])
if (ans[5] == 'B'):
return (ans[7] == ans[0] and ans[7] == ans[5])
if (ans[5] == 'C'):
return (ans[7] == ans[2] and ans[7] == ans[9])
if (ans[5] == 'D'):
return (ans[7] == ans[4] and ans[7] == ans[8])
def check_7(ans, selected_count):
idx = selected_count.index(min(selected_count))
return (ans[6] == 'A' and idx == 2) or (ans[6] == 'B' and idx == 1) or (ans[6] == 'C' and idx == 0) or (ans[6] == 'D' and idx == 3)
def check_8(ans):
return True
def check_9(ans):
return True
def check_10(ans, selected_count):
delta = max(selected_count) - min(selected_count)
return (ans[9] == 'A' and delta == 3) or (ans[9] == 'B' and delta == 2) or (ans[9] == 'C' and delta == 4) or (ans[9] == 'D' and delta == 1)
def check(ans):
if not check_2(ans):
return False
if not check_5(ans):
return False
if not check_6(ans):
return False
if not check_3(ans):
return False
# 上述四個條件下來,剩下 120 組
if not check_4(ans):
return False
# 上述五個條件下來,剩下 12 組
selected_count = [ans.count(x) for x in ['A', 'B', 'C', 'D']]
if not check_7(ans, selected_count):
return False
# 上述六個條件下來,剩下 2 組
if not check_10(ans, selected_count):
return False
# 上述七個條件下來,剩下以下 2 組 (這題白做工)
# ----------------------------------------
# ['B', 'C', 'A', 'C', 'A', 'C', 'D', 'A', 'B', 'A']
# ['D', 'C', 'A', 'C', 'A', 'C', 'B', 'A', 'D', 'A']
# total: 2
# ----------------------------------------
# 剩下兩組,乾脆就直接用推的:
# 還有 8, 9 兩題, 兩組中 8 的答案一樣,從 9 去看
return True
count = 0
for i in range(N):
d = to_base4(i)
ans = base4_to_abcd(d)
if check(ans):
print(ans)
count += 1
print("total:", count)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment