--- /dev/null
+""" Pair insertion """
+import collections
+
+insertion_rules = {}
+
+with open("14_input.txt") as f:
+ polymer_template = f.readline().strip()
+ f.readline()
+
+ for line in f:
+ pair, insert = line.strip().split(" -> ")
+
+ insertion_rules[pair] = insert
+
+extended_template = []
+
+expected_length = len(polymer_template)
+
+for gen in range(10):
+ for i in range(len(polymer_template) - 1):
+
+ pair = polymer_template[i:i+2]
+ extended_template += [
+ polymer_template[i],
+ insertion_rules[pair],
+ ]
+
+ polymer_template = "".join(
+ extended_template + [polymer_template[i + 1]]
+ )
+ extended_template = []
+ expected_length += expected_length - 1
+
+ assert len(polymer_template) == expected_length, "Length unexpected"
+
+letter_count = collections.defaultdict(int)
+for letter in polymer_template:
+ letter_count[letter] += 1
+
+print(max(letter_count.values()) - min(letter_count.values()))
--- /dev/null
+""" Pair insertion """
+import pprint
+import collections
+
+insertion_rules = {}
+
+polymer_pairs = collections.defaultdict(int)
+
+letter_count = collections.defaultdict(int)
+
+with open("14_input.txt") as f:
+ polymer_template = f.readline().strip()
+ f.readline()
+
+ for line in f:
+ pair, insert = line.strip().split(" -> ")
+ insertion_rules[pair] = insert
+
+for i in range(len(polymer_template) - 1):
+ pair = str(polymer_template[i:i+2])
+ polymer_pairs[str(polymer_template[i:i+2])] += 1
+
+print(polymer_pairs)
+
+for _ in range(40):
+ new_polymer_pairs = collections.defaultdict(int)
+ for pair, n in polymer_pairs.items():
+ insert = insertion_rules[pair]
+
+ new_polymer_pairs[f"{pair[0]}{insert}"] += n
+ new_polymer_pairs[f"{insert}{pair[0]}"] += n
+ letter_count[insert] += n
+
+ polymer_pairs = new_polymer_pairs
+
+print(letter_count)
+print(max(letter_count.values()) - min(letter_count.values()))