Day 14, part 1

This commit is contained in:
Zoé Cassiopée Gauthier 2021-12-14 11:39:00 -05:00
parent f3a5c52c4a
commit daaa7f9fb4
3 changed files with 188 additions and 0 deletions

View File

@ -54,3 +54,7 @@ path = "src/day12.rs"
[[bin]]
name = "day13"
path = "src/day13.rs"
[[bin]]
name = "day14"
path = "src/day14.rs"

102
inputs/day14.txt Normal file
View File

@ -0,0 +1,102 @@
CNBPHFBOPCSPKOFNHVKV
CS -> S
FB -> F
VK -> V
HO -> F
SO -> K
FK -> B
VS -> C
PS -> H
HH -> P
KH -> V
PV -> V
CB -> N
BB -> N
HB -> B
HV -> O
NC -> H
NF -> B
HP -> B
HK -> S
SF -> O
ON -> K
VN -> V
SB -> H
SK -> H
VH -> N
KN -> C
CC -> N
BF -> H
SN -> N
KP -> B
FO -> N
KO -> V
BP -> O
OK -> F
HC -> B
NH -> O
SP -> O
OO -> S
VC -> O
PC -> F
VB -> O
FF -> S
BS -> F
KS -> F
OV -> P
NB -> O
CF -> F
SS -> V
KV -> K
FP -> F
KC -> C
PF -> C
OS -> C
PN -> B
OP -> C
FN -> F
OF -> C
NP -> C
CK -> N
BN -> K
BO -> K
OH -> S
BH -> O
SH -> N
CH -> K
PO -> V
CN -> N
BV -> F
FV -> B
VP -> V
FS -> O
NV -> P
PH -> C
HN -> P
VV -> C
NK -> K
CO -> N
NS -> P
VO -> P
CP -> V
OC -> S
PK -> V
NN -> F
SC -> P
BK -> F
BC -> P
FH -> B
OB -> O
FC -> N
PB -> N
VF -> N
PP -> S
HS -> O
HF -> N
KK -> C
KB -> N
SV -> N
KF -> K
CV -> N
NO -> P

82
src/day14.rs Normal file
View File

@ -0,0 +1,82 @@
use std::collections::HashMap;
fn expand(depth: usize, left: char, right: char, rules: &[(char, char, char)], elements: &mut HashMap<char, usize>) {
if depth == 0 {
return;
}
match rules.iter().find(|rule| rule.0 == left && rule.1 == right) {
Some(rule) => {
let counter = elements.entry(rule.2).or_insert(0);
*counter += 1;
expand(depth - 1, left, rule.2, rules, elements);
expand(depth - 1, rule.2, right, rules, elements);
}
None => {}
}
}
fn polymerize(depth: usize, template: &str, rules: &[(char, char, char)]) -> (usize, usize) {
let mut elements: HashMap<char, usize> = HashMap::new();
let chars = template.chars().collect::<Vec<char>>();
for pair in chars.windows(2) {
let (left, right) = (pair[0], pair[1]);
let counter = elements.entry(left).or_insert(0);
*counter += 1;
expand(depth, left, right, rules, &mut elements);
}
// Add the last (right-side) element.
let counter = elements.entry(*chars.last().unwrap()).or_insert(0);
*counter += 1;
let least_common = elements.iter().min_by(|x, y| x.1.cmp(y.1)).unwrap().1;
let most_common = elements.iter().max_by(|x, y| x.1.cmp(y.1)).unwrap().1;
(*least_common, *most_common)
}
fn main() {
const INPUT: &str = include_str!("../inputs/day14.txt");
let (template, rules) = INPUT.split_once("\n\n").unwrap();
let (least_common, most_common) = polymerize(
10,
template,
&rules
.lines()
.map(|rule| rule.split_once(" -> ").unwrap())
.map(|(a, b)| {
let mut pair = a.chars();
(
pair.next().unwrap(),
pair.next().unwrap(),
b.chars().next().unwrap(),
)
})
.collect::<Vec<(char, char, char)>>(),
);
println!("solution {}", most_common - least_common);
}
#[test]
fn test_polymerize() {
let rules = [
('C', 'H', 'B'),
('H', 'H', 'N'),
('C', 'B', 'H'),
('N', 'H', 'C'),
('H', 'B', 'C'),
('H', 'C', 'B'),
('H', 'N', 'C'),
('N', 'N', 'C'),
('B', 'H', 'H'),
('N', 'C', 'B'),
('N', 'C', 'B'),
('N', 'B', 'B'),
('B', 'N', 'B'),
('B', 'B', 'N'),
('B', 'C', 'B'),
('C', 'C', 'N'),
('C', 'N', 'C'),
];
assert_eq!(polymerize(10, "NNCB", &rules), (161, 1749));
}