67 lines
1.9 KiB
Python
67 lines
1.9 KiB
Python
|
import matrix
|
||
|
import numpy as np
|
||
|
import pandas as pd
|
||
|
import shared
|
||
|
from pprint import pprint as pp
|
||
|
from collections import Counter
|
||
|
|
||
|
class Polymers:
|
||
|
def __init__(self, name):
|
||
|
self.load(name)
|
||
|
self.process()
|
||
|
|
||
|
def load(self, name):
|
||
|
rules = []
|
||
|
with open(name, "r") as f:
|
||
|
template = f.readline().rstrip()
|
||
|
f.readline()
|
||
|
for rule in f.readlines():
|
||
|
rules.append(rule.rstrip().split(" -> "))
|
||
|
self.template = template
|
||
|
self.rules = dict(rules)
|
||
|
|
||
|
def process(self):
|
||
|
# make a counter with letters grouped together in twos
|
||
|
self.pair_counter = Counter([self.template[i:i+2] for i in range(len(self.template) - 1)])
|
||
|
for x in range(40):
|
||
|
self.x = x
|
||
|
self.step()
|
||
|
self.totals()
|
||
|
|
||
|
def step(self):
|
||
|
# Start a new counter
|
||
|
step_counter = Counter()
|
||
|
|
||
|
# loop over the pairs in the old counter
|
||
|
for pair in self.pair_counter:
|
||
|
# expand a and c from the pair
|
||
|
a, c = pair
|
||
|
# get the new letter to add
|
||
|
b = self.rules[pair]
|
||
|
# increment the new pairs
|
||
|
step_counter[f"{a}{b}"] += self.pair_counter[pair]
|
||
|
step_counter[f"{b}{c}"] += self.pair_counter[pair]
|
||
|
# replace
|
||
|
self.pair_counter = step_counter
|
||
|
|
||
|
def totals(self):
|
||
|
# start a new letter counter
|
||
|
c = Counter()
|
||
|
# loop over the pairs
|
||
|
for pair in self.pair_counter:
|
||
|
# increment the first letter in the pair, the 2nd letter is already taken care of
|
||
|
c[pair[0]] += self.pair_counter[pair]
|
||
|
# add the final letter of the template, because it
|
||
|
# never gets a right pair so its silently ignored
|
||
|
c[self.template[-1]] += 1
|
||
|
|
||
|
print(max(c.values()) - min(c.values()), self.x)
|
||
|
|
||
|
|
||
|
def main():
|
||
|
p = Polymers(shared.get_fname(14))
|
||
|
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
main()
|