use nom::{ bytes::complete::tag, character::complete::{line_ending, space1, u64 as nom_u64}, combinator::map, multi::separated_list1, sequence::tuple, IResult, }; use std::fs; fn main() -> Result<(), Box> { let input = fs::read_to_string("inputs/day_6.txt")?; let parsed = RacePlan::multi_parser(&input).unwrap().1; for plan in parsed { dbg!(&plan.win_count_product()); } Ok(()) } #[derive(Debug)] struct RacePlan(Vec); #[derive(Debug)] struct RaceRecord { time: u64, distance: u64, } impl RacePlan { fn multi_parser(input: &str) -> IResult<&str, Vec> { separated_list1(line_ending, RacePlan::parser)(input) } fn parser(input: &str) -> IResult<&str, Self> { map( tuple(( tag("Time:"), space1, separated_list1(space1, nom_u64), line_ending, tag("Distance:"), space1, separated_list1(space1, nom_u64), )), |(_, _, times, _, _, _, distances)| { RacePlan( times .into_iter() .zip(distances.into_iter()) .map(|(time, distance)| RaceRecord { time, distance }) .collect(), ) }, )(input) } fn win_count_product(&self) -> usize { self.0.iter().map(|r| r.count_wins()).product() } } impl RaceRecord { fn count_wins(&self) -> usize { (1..self.time) .map(|charge_time| charge_time * (self.time - charge_time)) .filter(|distance| *distance > self.distance) .count() } }