From b3ccfb7a7db71e3db57fc44931fab12b1ac14046 Mon Sep 17 00:00:00 2001 From: Bert Peters Date: Wed, 6 Dec 2023 08:45:49 +0100 Subject: [PATCH] Implement 2023 day 6 part 2 --- 2023/benches/days.rs | 2 +- 2023/src/day06.rs | 49 +++++++++++++++++++++++++++++++++++++------- 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/2023/benches/days.rs b/2023/benches/days.rs index 5340d9d..9837fad 100644 --- a/2023/benches/days.rs +++ b/2023/benches/days.rs @@ -9,7 +9,7 @@ use criterion::Criterion; use aoc_2023::get_implementation; /// Number of days we have an implementation to benchmark -const DAYS_IMPLEMENTED: u8 = 5; +const DAYS_IMPLEMENTED: u8 = 6; fn read_input(day: u8) -> std::io::Result> { let input_path = format!("inputs/{day:02}.txt"); diff --git a/2023/src/day06.rs b/2023/src/day06.rs index 16e44fc..76e3b47 100644 --- a/2023/src/day06.rs +++ b/2023/src/day06.rs @@ -1,6 +1,8 @@ use nom::bytes::complete::tag; +use nom::character::complete::digit1; use nom::character::complete::newline; use nom::character::complete::space1; +use nom::multi::fold_many1; use nom::multi::many1; use nom::sequence::delimited; use nom::sequence::pair; @@ -10,12 +12,38 @@ use nom::IResult; use crate::common::parse_input; fn parse_race(i: &[u8]) -> IResult<&[u8], (Vec, Vec)> { - use nom::character::complete::u64; + let line = |header| { + delimited( + tag(header), + many1(preceded(space1, nom::character::complete::u64)), + newline, + ) + }; - pair( - delimited(tag("Time:"), many1(preceded(space1, u64)), newline), - delimited(tag("Distance:"), many1(preceded(space1, u64)), newline), - )(i) + pair(line("Time:"), line("Distance:"))(i) +} + +fn parse_long_race(i: &[u8]) -> IResult<&[u8], (u64, u64)> { + let line = |header| { + delimited( + tag(header), + fold_many1( + preceded(space1, digit1), + || 0, + |mut cur, sequence| { + for &c in sequence { + cur *= 10; + cur += u64::from(c - b'0'); + } + + cur + }, + ), + newline, + ) + }; + + pair(line("Time:"), line("Distance:"))(i) } fn ways(time: u64, distance: u64) -> u64 { @@ -42,8 +70,10 @@ pub fn part1(input: &[u8]) -> anyhow::Result { Ok(total.to_string()) } -pub fn part2(_input: &[u8]) -> anyhow::Result { - anyhow::bail!("Not implemented") +pub fn part2(input: &[u8]) -> anyhow::Result { + let (time, distance) = parse_input(input, parse_long_race)?; + + Ok(ways(time, distance).to_string()) } #[cfg(test)] @@ -56,4 +86,9 @@ mod tests { fn sample_part1() { assert_eq!(part1(SAMPLE).unwrap(), "288"); } + + #[test] + fn sample_part2() { + assert_eq!(part2(SAMPLE).unwrap(), "71503"); + } }