AoC2021/src/day07.rs

76 lines
2.0 KiB
Rust

use std::collections::HashMap;
use crate::Day;
use anyhow::Result;
pub struct Day07(HashMap<i32, i32>);
impl Day for Day07 {
fn init(content: String) -> Result<Self> {
let mut hm = HashMap::new();
for n in &content.split(',').map(str::parse).collect::<Result<Vec<_>, std::num::ParseIntError>>()? {
let entry = hm.entry(*n).or_insert(0);
*entry += 1;
}
Ok(Self(hm))
}
fn part1(&self) -> Result<String> {
let m = self.0.keys().copied().map(
|x| self.0.iter().map(
|(n, count)| (x - *n).abs() * (*count)
).sum::<i32>()
).min().ok_or_else(|| anyhow::Error::msg("Could not find min"))?;
Ok(format!("{}", m))
}
fn part2(&self) -> Result<String> {
let max = *self.0.keys().max().ok_or_else(|| anyhow::Error::msg("Could not find max"))?;
let m = (0..=max).map(
|x| self.0.iter().map(
|(n, count)| {
let n = (x - *n).abs();
(n * (n + 1) / 2) * (*count)
}
).sum::<i32>()
).min().ok_or_else(|| anyhow::Error::msg("Could not find min"))?;
Ok(format!("{}", m))
}
}
#[cfg(test)]
mod tests {
use crate::day07::Day07;
use crate::day::Day;
use anyhow::Result;
const INPUT: &str = "16,1,2,0,4,2,7,1,2,14";
#[test]
fn part1_test() -> Result<()> {
let d = Day07::init(INPUT.to_string())?;
assert_eq!("37", d.part1()?);
Ok(())
}
#[test]
fn part2_test() -> Result<()> {
let d = Day07::init(INPUT.to_string())?;
assert_eq!("168", d.part2()?);
Ok(())
}
#[test]
fn part1_real() -> Result<()> {
let d = Day07::init(crate::load_input("07")?)?;
assert_eq!("357353", d.part1()?);
Ok(())
}
#[test]
fn part2_real() -> Result<()> {
let d = Day07::init(crate::load_input("07")?)?;
assert_eq!("104822130", d.part2()?);
Ok(())
}
}