Solve 2016 day 11.
This commit is contained in:
89
2016/d11.py
Normal file
89
2016/d11.py
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
import sys
|
||||||
|
from itertools import combinations
|
||||||
|
from lib import *
|
||||||
|
|
||||||
|
TOP_FLOOR = 3
|
||||||
|
part_1 = False
|
||||||
|
if part_1:
|
||||||
|
# g0, c0, g1, c1, ... elevator
|
||||||
|
state = [0, 0, 1, 2, 1, 2, 1, 2, 1, 2, 0]
|
||||||
|
else:
|
||||||
|
state = [0, 0, 0, 0, 0, 0, 1, 2, 1, 2, 1, 2, 1, 2, 0]
|
||||||
|
|
||||||
|
|
||||||
|
def is_state_valid(state):
|
||||||
|
for floor in range(0, TOP_FLOOR + 1):
|
||||||
|
gens_on_floor = [i // 2 for i in range(0, len(state) - 1, 2) if state[i] == floor]
|
||||||
|
chips_on_floor = [i // 2 for i in range(1, len(state) - 1, 2) if state[i] == floor]
|
||||||
|
if len(gens_on_floor) > 0:
|
||||||
|
for c in chips_on_floor:
|
||||||
|
if not c in gens_on_floor:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
assert is_state_valid([0, 0, 1, 2, 1, 2, 1, 2, 1, 2, 0]) == True
|
||||||
|
assert is_state_valid([0, 0, 1, 0, 1, 2, 1, 2, 1, 2, 0]) == False
|
||||||
|
|
||||||
|
|
||||||
|
def is_end_state(state):
|
||||||
|
return all([o == TOP_FLOOR for o in state])
|
||||||
|
|
||||||
|
assert is_end_state([0, 0, 1, 0, 1, 2, 1, 2, 1, 2, 0]) == False
|
||||||
|
assert is_end_state([3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3]) == True
|
||||||
|
|
||||||
|
|
||||||
|
def next_states(state):
|
||||||
|
floor = state[-1]
|
||||||
|
objects_on_floor = [i for i in range(len(state) - 1) if state[i] == floor]
|
||||||
|
|
||||||
|
nstates = []
|
||||||
|
for o in objects_on_floor:
|
||||||
|
if floor > 0:
|
||||||
|
nstate = list(state)
|
||||||
|
nstate[o] -= 1
|
||||||
|
nstate[-1] -= 1
|
||||||
|
nstates.append(nstate)
|
||||||
|
if floor < TOP_FLOOR:
|
||||||
|
nstate = list(state)
|
||||||
|
nstate[o] += 1
|
||||||
|
nstate[-1] += 1
|
||||||
|
nstates.append(nstate)
|
||||||
|
|
||||||
|
for os in combinations(objects_on_floor, 2):
|
||||||
|
if floor > 0:
|
||||||
|
nstate = list(state)
|
||||||
|
for o in os:
|
||||||
|
nstate[o] -= 1
|
||||||
|
nstate[-1] -= 1
|
||||||
|
nstates.append(nstate)
|
||||||
|
if floor < TOP_FLOOR:
|
||||||
|
nstate = list(state)
|
||||||
|
for o in os:
|
||||||
|
nstate[o] += 1
|
||||||
|
nstate[-1] += 1
|
||||||
|
nstates.append(nstate)
|
||||||
|
return nstates
|
||||||
|
|
||||||
|
|
||||||
|
states = [state]
|
||||||
|
for step in range(1000):
|
||||||
|
nstates = []
|
||||||
|
seen = set()
|
||||||
|
for state in states:
|
||||||
|
|
||||||
|
statet = tuple(state)
|
||||||
|
if statet in seen:
|
||||||
|
continue
|
||||||
|
seen.add(statet)
|
||||||
|
|
||||||
|
for nstate in next_states(state):
|
||||||
|
if not is_state_valid(nstate):
|
||||||
|
continue
|
||||||
|
if is_end_state(nstate):
|
||||||
|
print(step + 1)
|
||||||
|
sys.exit(0)
|
||||||
|
nstates.append(nstate)
|
||||||
|
|
||||||
|
# Keep search space manageable with pretty bad pruning.
|
||||||
|
nstates.sort(reverse=True)
|
||||||
|
states = nstates[:20000]
|
||||||
Reference in New Issue
Block a user