commit working tree
parent
4534eccffd
commit
4e8c71543c
@ -0,0 +1,25 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "day14"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"itertools",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "either"
|
||||||
|
version = "1.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itertools"
|
||||||
|
version = "0.10.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3"
|
||||||
|
dependencies = [
|
||||||
|
"either",
|
||||||
|
]
|
@ -0,0 +1,9 @@
|
|||||||
|
[package]
|
||||||
|
name = "day14"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
itertools = "0.10.0"
|
@ -0,0 +1,86 @@
|
|||||||
|
https://adventofcode.com/2021/day/14
|
||||||
|
|
||||||
|
## \--- Day 14: Extended Polymerization ---
|
||||||
|
|
||||||
|
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:
|
||||||
|
|
||||||
|
[code]
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
[/code]
|
||||||
|
|
||||||
|
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 `N _C_ N _B_ C _H_
|
||||||
|
B`.
|
||||||
|
|
||||||
|
Here are the results of a few steps using the above rules:
|
||||||
|
|
||||||
|
[code]
|
||||||
|
|
||||||
|
Template: NNCB
|
||||||
|
After step 1: NCNBCHB
|
||||||
|
After step 2: NBCCNBBBCBHCB
|
||||||
|
After step 3: NBBBCNCCNBBNBNBBCHBHHBCHB
|
||||||
|
After step 4: NBBNBNBBCCNBCNCCNBBNBBNBBBNBBNBBCBHCBHHNHCBBCBHCB
|
||||||
|
|
||||||
|
[/code]
|
||||||
|
|
||||||
|
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?_
|
||||||
|
|
@ -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
|
@ -0,0 +1,5 @@
|
|||||||
|
Template: NNCB
|
||||||
|
After step 1: NCNBCHB
|
||||||
|
After step 2: NBCCNBBBCBHCB
|
||||||
|
After step 3: NBBBCNCCNBBNBNBBCHBHHBCHB
|
||||||
|
After step 4: NBBNBNBBCCNBCNCCNBBNBBNBBBNBBNBBCBHCBHHNHCBBCBHCB
|
@ -0,0 +1,102 @@
|
|||||||
|
CKKOHNSBPCPCHVNKHFFK
|
||||||
|
|
||||||
|
KO -> C
|
||||||
|
SO -> S
|
||||||
|
BF -> V
|
||||||
|
VN -> B
|
||||||
|
OV -> K
|
||||||
|
VH -> O
|
||||||
|
KV -> N
|
||||||
|
KB -> F
|
||||||
|
NB -> C
|
||||||
|
HS -> K
|
||||||
|
PF -> B
|
||||||
|
HB -> N
|
||||||
|
OC -> H
|
||||||
|
FS -> F
|
||||||
|
VV -> S
|
||||||
|
KF -> C
|
||||||
|
FN -> F
|
||||||
|
KP -> S
|
||||||
|
HO -> N
|
||||||
|
NH -> K
|
||||||
|
OO -> S
|
||||||
|
FB -> C
|
||||||
|
BP -> F
|
||||||
|
CH -> N
|
||||||
|
SN -> O
|
||||||
|
KN -> B
|
||||||
|
CV -> O
|
||||||
|
CC -> B
|
||||||
|
VB -> C
|
||||||
|
PH -> V
|
||||||
|
CO -> K
|
||||||
|
KS -> K
|
||||||
|
BK -> N
|
||||||
|
FH -> S
|
||||||
|
PV -> H
|
||||||
|
CB -> P
|
||||||
|
FO -> F
|
||||||
|
BB -> K
|
||||||
|
OB -> C
|
||||||
|
HH -> F
|
||||||
|
ON -> O
|
||||||
|
FK -> B
|
||||||
|
NF -> F
|
||||||
|
SV -> F
|
||||||
|
CP -> H
|
||||||
|
SS -> B
|
||||||
|
OP -> H
|
||||||
|
NS -> O
|
||||||
|
HK -> N
|
||||||
|
BC -> P
|
||||||
|
NV -> V
|
||||||
|
VS -> F
|
||||||
|
PC -> V
|
||||||
|
CS -> F
|
||||||
|
NP -> V
|
||||||
|
PS -> F
|
||||||
|
VC -> F
|
||||||
|
KK -> S
|
||||||
|
PO -> P
|
||||||
|
HF -> H
|
||||||
|
KC -> P
|
||||||
|
SF -> N
|
||||||
|
BV -> N
|
||||||
|
FF -> V
|
||||||
|
FV -> V
|
||||||
|
BO -> N
|
||||||
|
OS -> C
|
||||||
|
OF -> H
|
||||||
|
CN -> S
|
||||||
|
NO -> O
|
||||||
|
NC -> B
|
||||||
|
VK -> C
|
||||||
|
HN -> B
|
||||||
|
PK -> N
|
||||||
|
SK -> S
|
||||||
|
HV -> F
|
||||||
|
BH -> B
|
||||||
|
OK -> S
|
||||||
|
VO -> B
|
||||||
|
BS -> H
|
||||||
|
PP -> N
|
||||||
|
SC -> K
|
||||||
|
BN -> P
|
||||||
|
FC -> S
|
||||||
|
SB -> B
|
||||||
|
SH -> H
|
||||||
|
NN -> V
|
||||||
|
NK -> N
|
||||||
|
VF -> H
|
||||||
|
CF -> F
|
||||||
|
PB -> C
|
||||||
|
SP -> P
|
||||||
|
KH -> C
|
||||||
|
VP -> N
|
||||||
|
CK -> H
|
||||||
|
HP -> P
|
||||||
|
FP -> B
|
||||||
|
HC -> O
|
||||||
|
PN -> F
|
||||||
|
OH -> H
|
@ -0,0 +1,74 @@
|
|||||||
|
use itertools::Itertools;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::io::stdin;
|
||||||
|
use std::io::BufRead;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let stdin = stdin();
|
||||||
|
let mut lines = stdin.lock().lines().map(|l| l.unwrap());
|
||||||
|
let polymer_template = lines.next().unwrap();
|
||||||
|
lines.next();
|
||||||
|
|
||||||
|
let mut insertion_rules = HashMap::new();
|
||||||
|
for line in lines {
|
||||||
|
let mut elements = line.chars().filter(|c| c.is_ascii_alphabetic());
|
||||||
|
let a = elements.next().unwrap();
|
||||||
|
let b = elements.next().unwrap();
|
||||||
|
let c = elements.next().unwrap();
|
||||||
|
let pair = (a, b);
|
||||||
|
insertion_rules.insert(pair, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
dbg!(&polymer_template);
|
||||||
|
println!("Insertion rules: {:?}", insertion_rules);
|
||||||
|
|
||||||
|
let mut tuple_counter: HashMap<(char, char), i64> = HashMap::new();
|
||||||
|
|
||||||
|
for tuple in polymer_template.chars().tuple_windows() {
|
||||||
|
*tuple_counter.entry(tuple).or_insert(0) += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut step = 0;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let mut next_counter = HashMap::new();
|
||||||
|
for ((a, b), amount) in tuple_counter {
|
||||||
|
if let Some(c) = insertion_rules.get(&(a, b)) {
|
||||||
|
let c = *c;
|
||||||
|
*next_counter.entry((a, c)).or_insert(0) += amount;
|
||||||
|
*next_counter.entry((c, b)).or_insert(0) += amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let length = next_counter.values().sum::<i64>() + 1;
|
||||||
|
tuple_counter = next_counter;
|
||||||
|
|
||||||
|
step += 1;
|
||||||
|
println!("After step {}: Length {}", step, length);
|
||||||
|
if step >= 40 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut element_counter = HashMap::new();
|
||||||
|
for ((a, b), amount) in tuple_counter {
|
||||||
|
*element_counter.entry(a).or_insert(0) += amount;
|
||||||
|
*element_counter.entry(b).or_insert(0) += amount;
|
||||||
|
}
|
||||||
|
let first_element = polymer_template.chars().next().unwrap();
|
||||||
|
let last_element = polymer_template.chars().last().unwrap();
|
||||||
|
*element_counter.entry(first_element).or_insert(0) += 1;
|
||||||
|
*element_counter.entry(last_element).or_insert(0) += 1;
|
||||||
|
for amount in element_counter.values_mut() {
|
||||||
|
*amount >>= 1;
|
||||||
|
}
|
||||||
|
println!("Element counter {:?}", element_counter);
|
||||||
|
|
||||||
|
let mut amounts: Vec<&i64> = element_counter.values().collect();
|
||||||
|
amounts.sort();
|
||||||
|
let least_common = amounts.get(0).unwrap();
|
||||||
|
let most_common = amounts.last().unwrap();
|
||||||
|
let answer = *most_common - *least_common;
|
||||||
|
|
||||||
|
println!("{:?}", amounts);
|
||||||
|
dbg!(answer);
|
||||||
|
}
|
Loading…
Reference in New Issue