2021 Day 14
This commit is contained in:
parent
e2466aa44a
commit
5929e63062
68
2021/14/README.md
Normal file
68
2021/14/README.md
Normal file
@ -0,0 +1,68 @@
|
||||
# 2021 Day 14: Extended Polymerization
|
||||
Copyright (c) Eric Wastl
|
||||
#### [Direct Link](https://adventofcode.com/2021/day/14)
|
||||
|
||||
## Part 1
|
||||
|
||||
The incredible pressures at this depth are starting to put a strain on your submarine. The submarine has [polymerization](https://en.wikipedia.org/wiki/Polymerization) equipment that would produce suitable materials to reinforce the submarine, and the nearby volcanically-active caves should even have the necessary input elements in sufficient quantities.
|
||||
|
||||
The submarine manual contains instructions for finding the optimal polymer formula; specifically, it offers a **polymer template** and a list of **pair insertion** rules (your puzzle input). You just need to work out what polymer would result after repeating the pair insertion process a few times.
|
||||
|
||||
For example:
|
||||
|
||||
```
|
||||
NNCB
|
||||
|
||||
CH -> B
|
||||
HH -> N
|
||||
CB -> H
|
||||
NH -> C
|
||||
HB -> C
|
||||
HC -> B
|
||||
HN -> C
|
||||
NN -> C
|
||||
BH -> H
|
||||
NC -> B
|
||||
NB -> B
|
||||
BN -> B
|
||||
BB -> N
|
||||
BC -> B
|
||||
CC -> N
|
||||
CN -> C
|
||||
```
|
||||
|
||||
The first line is the **polymer template** - this is the starting point of the process.
|
||||
|
||||
The following section defines the **pair insertion** rules. A rule like `AB -> C` means that when elements `A` and `B` are immediately adjacent, element `C` should be inserted between them. These insertions all happen simultaneously.
|
||||
|
||||
So, starting with the polymer template `NNCB`, the first step simultaneously considers all three pairs:
|
||||
|
||||
- The first pair (`NN`) matches the rule `NN` -> `C`, so element `C` is inserted between the first `N` and the second `N`.
|
||||
- The second pair (`NC`) matches the rule `NC` -> `B`, so element `B` is inserted between the `N` and the `C`.
|
||||
- The third pair (`CB`) matches the rule `CB -> H`, so element `H is inserted between the `C` and the `B`.
|
||||
|
||||
Note that these pairs overlap: the second element of one pair is the first element of the next pair. Also, because all pairs are considered simultaneously, inserted elements are not considered to be part of a pair until the next step.
|
||||
|
||||
After the first step of this process, the polymer becomes `NCNBCHB`.
|
||||
|
||||
Here are the results of a few steps using the above rules:
|
||||
|
||||
```
|
||||
Template: NNCB
|
||||
After step 1: NCNBCHB
|
||||
After step 2: NBCCNBBBCBHCB
|
||||
After step 3: NBBBCNCCNBBNBNBBCHBHHBCHB
|
||||
After step 4: NBBNBNBBCCNBCNCCNBBNBBNBBBNBBNBBCBHCBHHNHCBBCBHCB
|
||||
```
|
||||
|
||||
This polymer grows quickly. After step 5, it has length 97; After step 10, it has length 3073. After step 10, `B` occurs 1749 times, `C` occurs 298 times, `H` occurs 161 times, and `N` occurs 865 times; taking the quantity of the most common element (B, 1749) and subtracting the quantity of the least common element (`H`, 161) produces `1749 - 161 = 1588`.
|
||||
|
||||
Apply 10 steps of pair insertion to the polymer template and find the most and least common elements in the result. **What do you get if you take the quantity of the most common element and subtract the quantity of the least common element?**
|
||||
|
||||
## Part 2
|
||||
|
||||
The resulting polymer isn't nearly strong enough to reinforce the submarine. You'll need to run more steps of the pair insertion process; a total of **40 steps** should do it.
|
||||
|
||||
In the above example, the most common element is `B` (occurring `2192039569602` times) and the least common element is `H` (occurring `3849876073` times); subtracting these produces **`2188189693529`**.
|
||||
|
||||
Apply **40** steps of pair insertion to the polymer template and find the most and least common elements in the result. **What do you get if you take the quantity of the most common element and subtract the quantity of the least common element?**
|
48
2021/14/code.py
Normal file
48
2021/14/code.py
Normal file
@ -0,0 +1,48 @@
|
||||
# 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)}")
|
102
2021/14/input.txt
Normal file
102
2021/14/input.txt
Normal file
@ -0,0 +1,102 @@
|
||||
HBCHSNFFVOBNOFHFOBNO
|
||||
|
||||
HF -> O
|
||||
KF -> F
|
||||
NK -> F
|
||||
BN -> O
|
||||
OH -> H
|
||||
VC -> F
|
||||
PK -> B
|
||||
SO -> B
|
||||
PP -> H
|
||||
KO -> F
|
||||
VN -> S
|
||||
OS -> B
|
||||
NP -> C
|
||||
OV -> C
|
||||
CS -> P
|
||||
BH -> P
|
||||
SS -> P
|
||||
BB -> H
|
||||
PH -> V
|
||||
HN -> F
|
||||
KV -> H
|
||||
HC -> B
|
||||
BC -> P
|
||||
CK -> P
|
||||
PS -> O
|
||||
SH -> N
|
||||
FH -> N
|
||||
NN -> P
|
||||
HS -> O
|
||||
CB -> F
|
||||
HH -> F
|
||||
SB -> P
|
||||
NB -> F
|
||||
BO -> V
|
||||
PN -> H
|
||||
VP -> B
|
||||
SC -> C
|
||||
HB -> H
|
||||
FP -> O
|
||||
FC -> H
|
||||
KP -> B
|
||||
FB -> B
|
||||
VK -> F
|
||||
CV -> P
|
||||
VF -> V
|
||||
SP -> K
|
||||
CC -> K
|
||||
HV -> P
|
||||
NC -> N
|
||||
VH -> K
|
||||
PF -> P
|
||||
PB -> S
|
||||
BF -> K
|
||||
FF -> C
|
||||
FV -> V
|
||||
KS -> H
|
||||
VB -> F
|
||||
SV -> F
|
||||
HO -> B
|
||||
FN -> C
|
||||
SN -> F
|
||||
OB -> N
|
||||
KN -> P
|
||||
BV -> H
|
||||
ON -> N
|
||||
NF -> S
|
||||
OF -> P
|
||||
NV -> S
|
||||
VS -> C
|
||||
OO -> C
|
||||
BP -> H
|
||||
BK -> N
|
||||
CP -> N
|
||||
PC -> K
|
||||
CN -> H
|
||||
KB -> B
|
||||
BS -> P
|
||||
KK -> P
|
||||
SF -> V
|
||||
CO -> V
|
||||
CH -> P
|
||||
FO -> B
|
||||
FS -> F
|
||||
VO -> H
|
||||
NS -> F
|
||||
KC -> H
|
||||
VV -> K
|
||||
NO -> P
|
||||
OK -> F
|
||||
PO -> V
|
||||
FK -> H
|
||||
OP -> H
|
||||
PV -> N
|
||||
CF -> P
|
||||
NH -> K
|
||||
SK -> O
|
||||
KH -> P
|
||||
HP -> V
|
||||
OC -> V
|
||||
HK -> F
|
2
2021/14/solution.txt
Normal file
2
2021/14/solution.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Part 1: 3408
|
||||
Part 2: 3724343376942
|
35
2021/14/test_code.py
Normal file
35
2021/14/test_code.py
Normal file
@ -0,0 +1,35 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2021 Akumatic
|
||||
|
||||
from code import part1, part2, read_file, count
|
||||
|
||||
def count_chars(s: str) -> dict:
|
||||
cnt = dict()
|
||||
for c in s:
|
||||
if c in cnt:
|
||||
cnt[c] += 1
|
||||
else:
|
||||
cnt[c] = 1
|
||||
return cnt
|
||||
|
||||
def test():
|
||||
vals = read_file("test_input.txt")
|
||||
assert count(vals[0], vals[1], 1) == count_chars("NCNBCHB")
|
||||
assert count(vals[0], vals[1], 2) == count_chars("NBCCNBBBCBHCB")
|
||||
assert count(vals[0], vals[1], 3) == count_chars("NBBBCNCCNBBNBNBBCHBHHBCHB")
|
||||
assert count(vals[0], vals[1], 4) == count_chars("NBBNBNBBCCNBCNCCNBBNBBNBBBNBBNBBCBHCBHHNHCBBCBHCB")
|
||||
print("Passed Counting")
|
||||
|
||||
elements = count(vals[0], vals[1], 10)
|
||||
assert elements == {"B": 1749, "C": 298, "H": 161, "N": 865}
|
||||
assert part1(*vals) == 1588
|
||||
print("Passed Part 1")
|
||||
|
||||
elements = count(vals[0], vals[1], 40)
|
||||
assert elements["B"] == 2192039569602
|
||||
assert elements["H"] == 3849876073
|
||||
assert part2(*vals) == 2188189693529
|
||||
print("Passed Part 2")
|
||||
|
||||
if __name__ == "__main__":
|
||||
test()
|
18
2021/14/test_input.txt
Normal file
18
2021/14/test_input.txt
Normal file
@ -0,0 +1,18 @@
|
||||
NNCB
|
||||
|
||||
CH -> B
|
||||
HH -> N
|
||||
CB -> H
|
||||
NH -> C
|
||||
HB -> C
|
||||
HC -> B
|
||||
HN -> C
|
||||
NN -> C
|
||||
BH -> H
|
||||
NC -> B
|
||||
NB -> B
|
||||
BN -> B
|
||||
BB -> N
|
||||
BC -> B
|
||||
CC -> N
|
||||
CN -> C
|
@ -28,7 +28,7 @@ Collect stars by solving puzzles. Two puzzles will be made available on each day
|
||||
| 11 | :white_check_mark: | :white_check_mark: | [Solution](11/code.py) | [Day 11](https://adventofcode.com/2021/day/11) |
|
||||
| 12 | :white_check_mark: | :white_check_mark: | [Solution](12/code.py) | [Day 12](https://adventofcode.com/2021/day/12) |
|
||||
| 13 | :white_check_mark: | :white_check_mark: | [Solution](13/code.py) | [Day 13](https://adventofcode.com/2021/day/13) |
|
||||
| 14 | | | | |
|
||||
| 14 | :white_check_mark: | :white_check_mark: | [Solution](14/code.py) | [Day 14](https://adventofcode.com/2021/day/14) |
|
||||
| 15 | | | | |
|
||||
| 16 | | | | |
|
||||
| 17 | | | | |
|
||||
|
Loading…
x
Reference in New Issue
Block a user