In [5]:
initial = '.##..#.#..##..##..##...#####.#.....#..#..##.###.#.####......#.......#..###.#.#.##.#.#.###...##.###.#'
In [6]:
r = ! cat input.txt | tr '\n' ';'
r = dict(list(map(lambda x: tuple(x.split(' => ')), r[0].split(';')[:-1])))
In [31]:
def evolve(state, rules, time):
s = state
for t in range(1, time + 1):
n = len(s)
s = '....' + s + '....'
new = []
for i in range(n + 5):
k = s[i: i + 5]
new.append(rules.get(k, '.'))
s = ''.join(new)
yield list(filter(lambda x: s[x + 2 * t] == '#', range(-2 * t, len(state) + 2 * t)))
def sumofpots(state, rules, time):
final = None
for l in evolve(state, rules, time):
final = l
return sum(final)
In [32]:
initial_test = '#..#.#..##......###...###'
rules_test = ! cat input_test.txt | tr '\n' ';'
rules_test = dict(list(map(lambda x: tuple(x.split(' => ')), rules_test[0].split(';')[:-1])))
In [33]:
sumofpots(initial_test, rules_test, 20)
Out[33]:
In [34]:
sumofpots(initial, r, 20)
Out[34]:
In [43]:
forever = 50000000000
In [62]:
def pattern_repetition(state, rules, time):
hashes = {}
period = None
for i, l in enumerate(evolve(state, rules, time)):
sig = hash(tuple([c - l[0] for c in l]))
if sig in hashes:
period = i - hashes[sig]
break
hashes[hash(sig)] = i
return i + 1, period, l
In [65]:
generation, period, l = pattern_repetition(initial, r, forever)
generation, period
Out[65]:
In [66]:
len(l) * (forever - generation) + sum(l)
Out[66]: