| @@ -0,0 +1,64 @@ | |||
| import re | |||
| import sys | |||
| def display(state): | |||
| ele, floors = state | |||
| for i, floor in list(enumerate(floors))[::-1]: | |||
| _ = ['E' if ele == i else ' '] | |||
| _ += [d if d in floor else '..' for d in sorted(devices)] | |||
| print(' '.join(_)) | |||
| print() | |||
| def checks(elevator, floors): | |||
| for fl in floors: | |||
| vulnerable = {d for d in fl if d == d.lower() and d.upper() not in fl} | |||
| dangerous = {d for d in fl if d == d.upper()} | |||
| if vulnerable and dangerous: | |||
| yield False | |||
| def moves(ith, floors): | |||
| for jth in {ith - 1, ith + 1} - {-1, 4}: | |||
| for stuff in [{a, b} for a in floors[ith] for b in floors[ith]]: | |||
| new = (jth, tuple( | |||
| (floor | stuff) if ith == jth else (floor - stuff) | |||
| for ith, floor in enumerate(floors) | |||
| )) | |||
| if all(checks(*new)): | |||
| yield new | |||
| text = sys.stdin.read() | |||
| start = [ | |||
| frozenset( | |||
| word[:2].upper() if not word.endswith('-') else word[:2] | |||
| for word in re.findall(r'\w+ium-?', ln) | |||
| ) | |||
| for ln in text.splitlines() | |||
| ] | |||
| start[2] -= {'PR', 'RU', 'pr', 'ru'} | |||
| # start[0] |= {'EE', 'ee', 'DD', 'dd'} | |||
| devices = frozenset({device for floor in start for device in floor}) | |||
| edge = {(0, tuple(start))} | |||
| goal = (3, tuple([frozenset(), frozenset(), frozenset(), devices])) | |||
| seen = {} | |||
| while goal not in seen: | |||
| edge = {new: old for old in edge for new in moves(*old) if new not in seen} | |||
| if not edge: | |||
| raise RuntimeError('empty') | |||
| seen = {**edge, **seen} | |||
| print(len(edge)) | |||
| seq = [] | |||
| while goal != (0, tuple(start)): | |||
| seq.append(goal) | |||
| goal = seen[goal] | |||
| seq.append(goal) | |||
| seq.reverse() | |||
| for i, state in enumerate(seq): | |||
| print(i) | |||
| display(state) | |||