|
- import collections
- import itertools
- import re
- import sys
-
-
- txt = '''90342 ;2 correct
- 70794 ;0 correct
- 39458 ;2 correct
- 34109 ;1 correct
- 51545 ;2 correct
- 12531 ;1 correct
- ''' # 39542 is unique
- txt = sys.stdin.read()
-
-
- exclusions = collections.defaultdict(set)
- clues = []
- for string, n in re.findall(r'(\d+) ;(\d)', txt):
- choices = set(enumerate(string))
- combos = [frozenset(cs) for cs in itertools.combinations(choices, int(n))]
- for combo in combos:
- exclusions[combo] |= (choices - combo)
- if int(n):
- clues.append(combos)
-
-
- for pos in range(len(string)):
- choices = {(pos, char) for char in '0123456789'}
- for choice in choices:
- exclusions[frozenset({choice})] |= (choices - {choice})
-
-
- def solve(clues_left, known=frozenset()):
- if not clues_left:
- avail = {a for gr in exclusions for a in gr}
- avail -= {v for k, vs in exclusions.items() if k <= known for v in vs}
- yield ''.join(c for _, c in sorted(avail))
-
- else:
- choices = min(clues_left, key=len)
- for choice in choices:
- chosen = known | choice
- bads = {v for k, vs in exclusions.items() if k <= chosen for v in vs}
- mods = [[c for c in cl if not c & bads] for cl in clues_left if cl != choices]
- yield from solve(mods, chosen)
-
-
- solution = next(solve(clues))
- print(solution)
|