#!/usr/bin/env python3 from pathlib import Path from collections import Counter, defaultdict def part_1(input): result = 0 template = input.pop(0).strip() input.pop(0) rules = {k.strip(): v.strip() for line in input for k, v in [line.strip().split('->')]} counts = defaultdict(int) for i in range(len(template) - 1): counts[template[i: i + 2]] += 1 for _ in range(10): tmp_cnts = counts.copy() for k in tmp_cnts: if k in rules: c = tmp_cnts[k] counts[k] -= c counts[k[0] + rules[k]] += c counts[rules[k] + k[1]] += c char_counts = defaultdict(int) for k in counts: char_counts[k[0]] += counts[k] char_counts[k[1]] += counts[k] char_counts[template[0]] += 1 char_counts[template[-1]] += 1 for k in char_counts: char_counts[k] //= 2 char_counts = sorted(char_counts.items(), key=lambda kv: kv[1]) result = char_counts[-1][1] - char_counts[0][1] print("Part 1 result:", result) def part_2(input): result = 0 template = input.pop(0).strip() input.pop(0) rules = {k.strip(): v.strip() for line in input for k, v in [line.strip().split('->')]} counts = defaultdict(int) for i in range(len(template) - 1): counts[template[i: i + 2]] += 1 for _ in range(40): tmp_cnts = counts.copy() for k in tmp_cnts: if k in rules: c = tmp_cnts[k] counts[k] -= c counts[k[0] + rules[k]] += c counts[rules[k] + k[1]] += c char_counts = defaultdict(int) for k in counts: char_counts[k[0]] += counts[k] char_counts[k[1]] += counts[k] char_counts[template[0]] += 1 char_counts[template[-1]] += 1 for k in char_counts: char_counts[k] //= 2 char_counts = sorted(char_counts.items(), key=lambda kv: kv[1]) result = char_counts[-1][1] - char_counts[0][1] print("Part 2 result:", result) input = list() p = Path(__file__).with_name('input.txt') with open(p) as f: input = f.readlines() part_1(input.copy()) part_2(input.copy())