use nom::{ character::complete::{line_ending, u64 as nom_u64}, combinator::map, multi::separated_list1, IResult, }; use std::fs; fn main() -> Result<(), Box> { let input = fs::read_to_string("inputs/day_1.txt")?; let sonar_scan = parse_sonar_scan(&input).unwrap().1; let simple_increase_counter = count_increases(sonar_scan.iter()); dbg!(simple_increase_counter); let windowed_sonar_scan = sonar_scan .iter() .zip(sonar_scan.iter().skip(1)) .zip(sonar_scan.iter().skip(2)) .map(|((depth1, depth2), depth3)| ThreeDepthWindowSum::new([*depth1, *depth2, *depth3])) .collect::>(); let windowed_increase_counter = count_increases(windowed_sonar_scan.iter()); dbg!(windowed_increase_counter); Ok(()) } #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] struct Depth(u64); #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] struct ThreeDepthWindowSum(u64); impl ThreeDepthWindowSum { fn new(depths: [Depth; 3]) -> ThreeDepthWindowSum { ThreeDepthWindowSum(depths.into_iter().map(|d| d.0).sum()) } } fn parse_sonar_scan(input: &str) -> IResult<&str, Vec> { separated_list1(line_ending, parse_depth)(input) } fn parse_depth(input: &str) -> IResult<&str, Depth> { map(nom_u64, Depth)(input) } #[derive(Default, Debug)] struct DepthIncreaseCounter(u64); impl DepthIncreaseCounter { fn increment(&mut self) { self.0 += 1; } } fn count_increases(i: impl IntoIterator + Clone) -> DepthIncreaseCounter { let mut increases = DepthIncreaseCounter::default(); for (depth, next_depth) in i.clone().into_iter().zip(i.into_iter().skip(1)) { if next_depth > depth { increases.increment(); } } increases } #[cfg(test)] mod tests { use super::*; #[test] fn parses_a_depth() { assert_eq!(parse_depth("96\n"), Ok(("\n", Depth(96)))); } }