From 127dcee141405210cc6b35cf66e70f71e2133ae5 Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Tue, 14 Dec 2021 11:05:49 -0500 Subject: [PATCH] Day 14 --- input/day14.txt | 102 +++++++++++++++++++++++++++++++++++++++++++ src/day14.rs | 114 ++++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 3 +- 3 files changed, 218 insertions(+), 1 deletion(-) create mode 100644 input/day14.txt create mode 100644 src/day14.rs diff --git a/input/day14.txt b/input/day14.txt new file mode 100644 index 0000000..669d746 --- /dev/null +++ b/input/day14.txt @@ -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 diff --git a/src/day14.rs b/src/day14.rs new file mode 100644 index 0000000..9f55833 --- /dev/null +++ b/src/day14.rs @@ -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::>(); + + (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 { +// 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::>(); + v.sort(); + *v.last().unwrap() - *v.first().unwrap() +} diff --git a/src/main.rs b/src/main.rs index 34b1834..33f1f37 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,7 +12,8 @@ mod day10; mod day11; mod day12; mod day13; +mod day14; fn main() { - day13::day13(); + day14::day14(); }