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