Bladeren bron

2016/11

master
Roderic Day 4 jaren geleden
bovenliggende
commit
ef70f73fd1
1 gewijzigde bestanden met toevoegingen van 32 en 48 verwijderingen
  1. +32
    -48
      y2016/p11.py

+ 32
- 48
y2016/p11.py Bestand weergeven

@@ -2,63 +2,47 @@ 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 freeze(state):
return tuple(frozenset(fl) for fl in state)


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:
def thaw(state):
return [set(fl) for fl in state]


def checks(state):
for fl in state:
dangerous = {d[:-1] for d in fl if d.endswith('+')}
vulnerable = {d[:-1] for d in fl if d.endswith('-')} - dangerous
if dangerous and vulnerable:
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
def advance(pair):
f0, state = pair
for devices in {frozenset({a, b}) for a in state[f0] for b in state[f0]}:
for f1 in {f0 + 1, f0 - 1} - {-1, 4}:
if len(devices) == 1 or f1 > f0:
new = thaw(state)
new[f0] -= devices
new[f1] |= devices
if all(checks(new)):
yield f1, freeze(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)
)
state = [
{a + (b or '+') for a, b in re.findall(r'(\w{2})\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 = {}
goal = (3, freeze([{}, {}, {}, {d for fl in state for d in fl}]))
edge = {(0, freeze(state))}
seen = set()
ans1 = 0
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)
edge = {new for old in edge for new in advance(old)} - seen
seen |= edge
ans1 += 1
print(ans1)
print(ans1 + 12 * 2)

Laden…
Annuleren
Opslaan