This commit is contained in:
Shadowfacts 2021-12-14 11:05:49 -05:00
parent 7b313769db
commit 127dcee141
3 changed files with 218 additions and 1 deletions

102
input/day14.txt Normal file
View File

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

114
src/day14.rs Normal file
View File

@ -0,0 +1,114 @@
use std::collections::HashMap;
pub fn day14() {
// let input = r#"
// 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
// "#;
let input = include_str!("../input/day14.txt");
let (s, rules) = parse(input);
let mut pair_counts = count_pairs(s);
// dbg!(&pair_counts);
for _step in 0..10 {
pair_counts = step(&pair_counts, &rules);
}
println!(
"{}",
frequency_diff(&pair_counts, s.chars().last().unwrap())
);
for _step in 10..40 {
pair_counts = step(&pair_counts, &rules);
}
println!(
"{}",
frequency_diff(&pair_counts, s.chars().last().unwrap())
);
}
fn parse(input: &str) -> (&str, HashMap<(char, char), char>) {
let (s, rules) = input.trim().split_once("\n\n").unwrap();
let map = rules
.lines()
.map(|l| {
let (src, insertion) = l.trim().split_once(" -> ").unwrap();
(
(src.chars().nth(0).unwrap(), src.chars().nth(1).unwrap()),
insertion.chars().nth(0).unwrap(),
)
})
.collect::<HashMap<_, _>>();
(s, map)
}
fn count_pairs(s: &str) -> HashMap<(char, char), usize> {
let mut map = HashMap::new();
for pair in s.chars().zip(s.chars().skip(1)) {
*map.entry(pair).or_insert(0) += 1;
}
map
}
// fn replace(s: &[char], rules: &HashMap<(char, char), char>) -> Vec<char> {
// let mut res = s.to_vec();
// for ((i, a), b) in s.iter().enumerate().zip(s.iter().skip(1)).rev() {
// match rules.get(&(*a, *b)) {
// Some(insertion) => {
// res.insert(i + 1, *insertion);
// }
// _ => (),
// }
// }
// res
// }
fn step(
counts: &HashMap<(char, char), usize>,
rules: &HashMap<(char, char), char>,
) -> HashMap<(char, char), usize> {
let mut new_counts = HashMap::new();
for (pair, n) in counts {
if let Some(insertion) = rules.get(pair) {
*new_counts.entry((pair.0, *insertion)).or_insert(0) += n;
*new_counts.entry((*insertion, pair.1)).or_insert(0) += n;
} else {
new_counts.insert(*pair, *n);
}
}
new_counts
}
fn frequency_diff(pair_counts: &HashMap<(char, char), usize>, last_char: char) -> usize {
let mut frequencies = HashMap::new();
for ((a, _), n) in pair_counts {
*frequencies.entry(a).or_insert(0) += n;
// each char in what would be the actual string appears in two pairs, so only count the
// first char in each pair to avoid double counting
// this means which ever char would come last in the actual string is undercounted by 1, so
// add that back at the end
}
*frequencies.entry(&last_char).or_insert(0) += 1;
let mut v = frequencies.values().collect::<Vec<_>>();
v.sort();
*v.last().unwrap() - *v.first().unwrap()
}

View File

@ -12,7 +12,8 @@ mod day10;
mod day11;
mod day12;
mod day13;
mod day14;
fn main() {
day13::day13();
day14::day14();
}