|
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364 |
- 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)
|