61 lines
1.5 KiB
Python
61 lines
1.5 KiB
Python
def score(state, offset):
|
|
r = 0
|
|
for i in range(len(state)):
|
|
if state[i] == "#":
|
|
r += i + offset
|
|
return r
|
|
|
|
|
|
def solve(data, target_i):
|
|
state = None
|
|
map = {}
|
|
for line in data.splitlines():
|
|
if "initial state" in line:
|
|
_, rest = line.split(":")
|
|
state = rest.strip()
|
|
if "=>" in line:
|
|
lhs, rhs = line.split(" => ")
|
|
assert lhs not in map
|
|
map[lhs] = rhs
|
|
|
|
assert state is not None
|
|
seen = {}
|
|
offset = 0
|
|
for i in range(target_i):
|
|
while not state.startswith("...."):
|
|
state = "." + state
|
|
offset -= 1
|
|
while not state.endswith("...."):
|
|
state += "."
|
|
|
|
if state in seen:
|
|
prev_i, prev_score = seen[state]
|
|
assert (i - prev_i) == 1
|
|
current_score = score(state, offset)
|
|
delta_score = current_score - prev_score
|
|
final_score = current_score + (target_i - i) * delta_score
|
|
print(final_score)
|
|
return
|
|
else:
|
|
seen[state] = (i, score(state, offset))
|
|
|
|
ns = ""
|
|
for i in range(2, len(state) - 2):
|
|
s = state[i - 2 : i + 3]
|
|
ns += map[s]
|
|
state = ns
|
|
offset += 2
|
|
print(score(state, offset))
|
|
|
|
|
|
def main():
|
|
input_file = __file__.replace(".py", ".txt")
|
|
with open(input_file) as f:
|
|
data = f.read()
|
|
solve(data, 20)
|
|
solve(data, 50 * 10**9)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|