advent/2021/src/day14.rs
2021-12-13 21:52:05 -08:00

105 lines
2.1 KiB
Rust

use std::{
collections::HashMap,
fmt::{Debug, Error, Formatter},
num::ParseIntError,
ops::{Index, IndexMut},
str::FromStr,
};
use anyhow::Result;
use aoc_runner_derive::{aoc, aoc_generator};
use thiserror::Error;
fn expand(template: &[u8], rules: &HashMap<&[u8], u8>) -> Vec<u8> {
let mut res = vec![0u8; template.len() * 2 - 1];
template.windows(2).enumerate().for_each(|(i, xy)| {
let z = rules[xy];
res[i * 2] = xy[0];
res[i * 2 + 1] = z;
res[i * 2 + 2] = xy[1];
});
//dbg!(String::from_utf8_lossy(&res));
res
}
fn count(template: &[u8]) -> (usize, usize) {
let m = template
.iter()
.fold(HashMap::<u8, usize>::new(), |mut m, v| {
*m.entry(*v).or_insert(0) += 1;
m
});
m.values()
.fold((usize::MAX, 0), |(min, max), v| (min.min(*v), max.max(*v)))
}
#[aoc(day14, part1)]
fn part1(input: &str) -> Result<usize> {
let (template, rules) = input.split_once("\n\n").unwrap();
let rules: HashMap<&[u8], u8> = rules
.lines()
.map(|l| {
let (pair, insert) = l.split_once(" -> ").unwrap();
(pair.as_bytes(), insert.as_bytes()[0])
})
.collect();
let mut template = template.as_bytes().to_vec();
for i in 1..11 {
template = expand(&template, &rules);
//println!("After step {}: {}", i, String::from_utf8_lossy(&template));
}
let (min, max) = count(&template);
Ok(max - min)
}
/*
#[aoc(day14, part2)]
fn part2(input: &[u64]) -> Result<u64> {
todo!("part2");
Ok(0)
}
*/
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_part1() -> Result<()> {
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
"#
.trim();
assert_eq!(part1(input)?, 1588);
Ok(())
}
/*
#[test]
fn test_part2()->Result<()> {
let input = r#"
"#
.trim();
assert_eq!(part2(&parse(input)?)?, u64::MAX);
Ok(())
}
*/
}