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()