From 24430cf1daa4a967e6a410df102a153ebfd52e57 Mon Sep 17 00:00:00 2001 From: Bert Peters Date: Mon, 18 Dec 2023 20:52:05 +0100 Subject: [PATCH] Implement 2023 day 18 part 2 This was not at all the twist I expected, but I like it. --- 2023/src/day18.rs | 46 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/2023/src/day18.rs b/2023/src/day18.rs index 709a530..3671760 100644 --- a/2023/src/day18.rs +++ b/2023/src/day18.rs @@ -1,8 +1,11 @@ +use anyhow::Context; use nom::bytes::complete::tag; use nom::bytes::complete::take; +use nom::bytes::complete::take_until; use nom::combinator::map; use nom::combinator::map_res; use nom::multi::many1; +use nom::sequence::delimited; use nom::sequence::pair; use nom::sequence::terminated; use nom::IResult; @@ -88,8 +91,42 @@ pub fn part1(input: &[u8]) -> anyhow::Result { solve(&digs) } -pub fn part2(_input: &[u8]) -> anyhow::Result { - anyhow::bail!("Not implemented") +fn parse_colors(i: &[u8]) -> IResult<&[u8], Vec> { + fn parse_color(i: &[u8]) -> anyhow::Result { + // stdlib offers hex parsing but requires going through string, incurring utf-8 validation. + // better do it ourselves. + let mut num = 0; + + for &c in &i[1..] { + num *= 16; + num += (c as char).to_digit(16).context("Invalid hex")?; + } + + Ok(num.into()) + } + many1(delimited( + take_until("#"), + map_res(take(7usize), |color: &[u8]| -> anyhow::Result { + let num = parse_color(color)?; + let amount = num >> 4; + + let dir = match num & 0xF { + 0 => Direction::Right, + 1 => Direction::Down, + 2 => Direction::Left, + 3 => Direction::Up, + other => anyhow::bail!("Unknown direction: {other}"), + }; + + Ok(Dig { dir, amount }) + }), + tag(")\n"), + ))(i) +} + +pub fn part2(input: &[u8]) -> anyhow::Result { + let digs = parse_input(input, parse_colors)?; + solve(&digs) } #[cfg(test)] @@ -102,4 +139,9 @@ mod tests { fn sample_part1() { assert_eq!("62", part1(SAMPLE).unwrap()); } + + #[test] + fn sample_part2() { + assert_eq!("952408144115", part2(SAMPLE).unwrap()); + } }