Skip to content

Instantly share code, notes, and snippets.

@xaedes
Created February 25, 2018 11:46
Show Gist options
  • Save xaedes/39012be25b61872cae454eb91723bcd0 to your computer and use it in GitHub Desktop.
Save xaedes/39012be25b61872cae454eb91723bcd0 to your computer and use it in GitHub Desktop.
threeruleslogic
# solution for 9gag.com/gag/a1oXmYw
def match(c1,c2):
intersection = set(c1).intersection(set(c2))
match_result = []
for digit in intersection:
idxs1 = [k for k,d in enumerate(c1) if digit==d]
idxs2 = [k for k,d in enumerate(c2) if digit==d]
for i in idxs1:
for k in idxs2:
match_result.append((digit,i,k))
return match_result
def sum_well_placed(match_result):
return sum([1 for (d,i,k) in match_result if (i==k)])
def sum_wrong_placed(match_result):
return sum([1 for (d,i,k) in match_result if (i!=k)])
def rule1(code):
# one number is correct and well placed : [6,8,2]
m = match(code, [6,8,2])
return (len(m) == 1) and (sum_well_placed(m) == 1)
def rule2(code):
# one number is correct but wrong place : [6,1,4]
m = match(code, [6,1,4])
return (len(m) == 1) and (sum_wrong_placed(m) == 1)
def rule3(code):
# two numbers are correct but wrong place : [2,0,6]
m = match(code, [2,0,6])
return (len(m) == 2) and (sum_wrong_placed(m) == 2)
def rule4(code):
# nothing is correct : [7,3,8]
m = match(code, [7,3,8])
return (len(m) == 0)
def rule5(code):
# one number is correct but wrong place : [8,7,0]
m = match(code, [8,7,0])
return (len(m) == 1) and (sum_wrong_placed(m) == 1)
def rules(code):
return rule1(code) and rule2(code) and rule3(code) and rule4(code) and rule5(code)
digits = range(10)
all_codes = [[a,b,c] for a in digits for b in digits for c in digits]
def check_codes(codes, rules_checker):
return [code for code in codes if rules_checker(code)]
print(check_codes(all_codes, rules))
# [[0, 4, 2]]
# is there a subset of the five rules that is sufficent to find the unique solution?
def rules_conf(conf, code):
all_rules=[rule1,rule2,rule3,rule4,rule5]
result = True
for k,rule in enumerate(all_rules):
if conf[k]:
result = result and rule(code)
return result
def check_codes_conf(codes, conf):
return check_codes(codes,(lambda c:rules_conf(conf,c)))
all_confs = [[a,b,c,d,e] for a in [False,True] for b in [False,True] for c in [False,True] for d in [False,True] for e in [False,True]]
# all rule subsets sorted by their corresponding number of unique solutions
print(sorted([(len(check_codes_conf(all_codes,conf)),conf) for conf in all_confs]))
# apparently the first three rules are sufficent:
# [(1, [True, True, True, False, False]),
# (1, [True, True, True, False, True]),
# (1, [True, True, True, True, False]),
# (1, [True, True, True, True, True]),
# (3, [True, True, False, True, True]),
# (4, [False, True, True, True, True]),
# (4, [True, False, True, True, True]),
# (5, [True, False, True, False, True]),
# (6, [False, True, True, False, True]),
# (8, [True, False, True, True, False]),
# (9, [True, True, False, True, False]),
# (12, [False, False, True, True, True]),
# (12, [True, False, False, True, True]),
# (13, [False, True, True, True, False]),
# (13, [True, False, True, False, False]),
# (13, [True, True, False, False, True]),
# (22, [False, False, True, False, True]),
# (22, [False, True, True, False, False]),
# (24, [False, True, False, True, True]),
# (30, [True, True, False, False, False]),
# (48, [False, False, True, True, False]),
# (50, [True, False, False, False, True]),
# (50, [True, False, False, True, False]),
# (72, [False, False, False, True, True]),
# (84, [False, False, True, False, False]),
# (96, [False, True, False, False, True]),
# (96, [False, True, False, True, False]),
# (147, [True, False, False, False, False]),
# (294, [False, False, False, False, True]),
# (294, [False, True, False, False, False]),
# (343, [False, False, False, True, False]),
# (1000, [False, False, False, False, False])]
check_codes_conf(all_codes, [True, True, True, False, False])
# [[0, 4, 2]]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment