2018 Day 12 proper
This commit is contained in:
parent
55250c9d64
commit
9b0784cdec
|
@ -1,34 +1,41 @@
|
||||||
with open('day12-input', 'r') as file:
|
with open('day12-input', 'r') as file:
|
||||||
data = [l.strip('\n') for l in file]
|
data = [l.strip('\n') for l in file]
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import re
|
|
||||||
|
|
||||||
# numbers = np.array([[int(s) for s in re.findall(r'-?\d+', d)] for d in data], dtype=np.int64)
|
initial_state = np.array([False if s=='.' else True for s in data[0].split()[-1]], dtype=np.bool)
|
||||||
max_gens = 50000000000
|
rules_list = [(sum([0 if s=='.' else 2**i for i, s in enumerate(d.split()[0])]), False if d.split()[-1] == '.' else True)
|
||||||
|
for d in data[2:]]
|
||||||
initial_state = np.array([0 if s=='.' else 1 for s in data[0].split()[-1]])
|
rules = np.array([v for k, v in sorted(rules_list)], dtype=np.bool)
|
||||||
rules = [np.array([0 if s=='.' else 1 for s in d.split()[0]]+[0 if s=='.' else 1 for s in d.split()[-1]]) for d in data[2:]]
|
r_transform = np.array([1, 2, 4, 8, 16], dtype=np.int64)
|
||||||
|
state = set(*initial_state.nonzero())
|
||||||
|
|
||||||
|
|
||||||
l = len(initial_state)
|
def perform_generation(input_state):
|
||||||
state = np.zeros(l*20, dtype=np.int64)
|
working_state = set()
|
||||||
state[l*10:l*11] = initial_state
|
adj = np.array([-2, -1, 0, 1, 2], dtype=np.int64)
|
||||||
last_state = state.copy()
|
check_set = {i+j for i in input_state for j in adj}
|
||||||
pots = np.arange(-l*10, l*10)
|
for pot in check_set:
|
||||||
|
if rules[(r_transform * [p in input_state for p in pot+adj]).sum()]:
|
||||||
|
working_state.add(pot)
|
||||||
|
return working_state
|
||||||
|
|
||||||
for gen in range(max_gens):
|
|
||||||
print(''.join(['#' if s else '.' for s in state[l*10-2:l*11+5]]), gen, max_gens-gen)
|
|
||||||
for plant in range(2, len(state)-2):
|
|
||||||
s = last_state[plant-2:plant+3]
|
|
||||||
matched = False
|
|
||||||
for rule in rules:
|
|
||||||
if np.array_equal(rule[:-1], s):
|
|
||||||
state[plant] = rule[-1]
|
|
||||||
# print('Matched!', rule)
|
|
||||||
matched = True
|
|
||||||
break
|
|
||||||
if not matched:
|
|
||||||
state[plant] = 0
|
|
||||||
last_state[:] = state[:]
|
|
||||||
|
|
||||||
print(pots[state > 0].sum())
|
for gen in range(20):
|
||||||
|
state = perform_generation(state)
|
||||||
|
val = sum(state)
|
||||||
|
print(val) # Part 1
|
||||||
|
|
||||||
|
state_2 = state.copy()
|
||||||
|
last_val = val
|
||||||
|
last_deltas = [None, None, None, None]
|
||||||
|
LAST_GEN = 50000000000
|
||||||
|
for gen in range(20, LAST_GEN):
|
||||||
|
if gen % 20 == 0:
|
||||||
|
val = sum(state_2)
|
||||||
|
last_deltas.append(val-last_val)
|
||||||
|
last_val = val
|
||||||
|
if len(set(last_deltas)) == 1: # If all the last few deltas are identical, give up
|
||||||
|
print(val + (last_deltas[0]*(LAST_GEN-gen)//20)) # Part 2
|
||||||
|
break
|
||||||
|
last_deltas.pop(0)
|
||||||
|
state_2 = perform_generation(state_2)
|
||||||
|
|
Loading…
Reference in New Issue