advent-of-code/2021/python/day14.py

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