49 lines
1.6 KiB
Python
49 lines
1.6 KiB
Python
# SPDX-License-Identifier: MIT
|
|
# Copyright (c) 2021 Akumatic
|
|
#
|
|
# https://adventofcode.com/2021/day/14
|
|
|
|
def read_file(filename: str = "input.txt") -> tuple:
|
|
with open(f"{__file__.rstrip('code.py')}{filename}", "r") as f:
|
|
lines = [line for line in f.read().strip().split("\n")]
|
|
template = lines[0]
|
|
rules = {x[0]: x[1] for x in (line.split(" -> ") for line in lines[2:])}
|
|
return template, rules
|
|
|
|
def add_to_dict(d: dict, key: str, val: int = 1):
|
|
if key not in d:
|
|
d[key] = val
|
|
else:
|
|
d[key] += val
|
|
|
|
def count(polymer: str, rules: dict, iterations: int) -> dict:
|
|
pairs = dict()
|
|
for i in range(len(polymer) - 1):
|
|
add_to_dict(pairs, polymer[i] + polymer[i+1])
|
|
|
|
for _ in range(iterations):
|
|
tmp = dict()
|
|
for pair in pairs:
|
|
add_to_dict(tmp, pair[0] + rules[pair], pairs[pair])
|
|
add_to_dict(tmp, rules[pair] + pair[1], pairs[pair])
|
|
pairs = tmp
|
|
|
|
elements = dict()
|
|
for pair in pairs:
|
|
add_to_dict(elements, pair[0], pairs[pair])
|
|
add_to_dict(elements, polymer[-1])
|
|
return elements
|
|
|
|
def part1(template: str, insertion_rules: dict) -> int:
|
|
letters = count(template, insertion_rules, 10)
|
|
return max(letters.values()) - min(letters.values())
|
|
|
|
def part2(template: str, insertion_rules: dict) -> int:
|
|
letters = count(template, insertion_rules, 40)
|
|
return max(letters.values()) - min(letters.values())
|
|
|
|
if __name__ == "__main__":
|
|
vals = read_file() # vals[0] is the template, vals[1] the insertion rules
|
|
print(f"Part 1: {part1(*vals)}")
|
|
print(f"Part 2: {part2(*vals)}")
|