-
Notifications
You must be signed in to change notification settings - Fork 0
/
day14.py
71 lines (52 loc) · 1.78 KB
/
day14.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import argparse
import os
from collections import Counter
from functools import cache
def insert_char(pair: str, ins: str) -> (str, str):
return pair[0] + ins, ins + pair[1]
@cache
def simulate(pair: str, steps: int) -> Counter:
if steps <= 0:
return Counter(pair)
left, right = insert_char(pair, rules[pair])
return simulate(left, steps - 1) + simulate(right, steps - 1) - Counter(rules[pair])
def score(counter: Counter) -> int:
common = counter.most_common()
most = common[0][1]
least = common[-1][1]
return most - least
def get_pairs(template: str) -> list[str]:
return [template[i : i + 2] for i in range(len(template) - 1)]
def read_input(filepath: str) -> (str, dict[str, str]):
rules = dict()
with open(filepath, "r") as f:
template = f.readline().rstrip()
f.readline()
for line in f.readlines():
data = line.split("->")
rules[data[0].strip()] = data[1].strip()
return template, rules
def init_parser() -> str:
parser = argparse.ArgumentParser(description="Advent of Code day 14 solution.")
parser.add_argument(
"input", metavar="FILE", type=str, nargs=1, help="Path to input data."
)
args = parser.parse_args()
return os.path.realpath(args.input[0])
if __name__ == "__main__":
path = init_parser()
template, rules = read_input(path)
pairs = get_pairs(template)
dont_double_count = Counter(template[1:-1])
part1 = Counter()
for pair in pairs:
part1 += simulate(pair, 10)
part1 -= dont_double_count
print(f"Part 1: {score(part1)}")
part2 = Counter()
for pair in pairs:
part2 += simulate(pair, 40)
part2 -= dont_double_count
print(f"Part 2: {score(part2)}")
def main(_):
raise NotImplementedError