From 681ef52b88c4b53b86fdc5bf45db19271253b108 Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Sun, 10 Dec 2023 14:15:56 -0500 Subject: day 10 part 2 --- src/bin/2023/day10.rs | 95 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 77 insertions(+), 18 deletions(-) diff --git a/src/bin/2023/day10.rs b/src/bin/2023/day10.rs index ef055e5..07e9741 100644 --- a/src/bin/2023/day10.rs +++ b/src/bin/2023/day10.rs @@ -68,21 +68,7 @@ impl Tile { } } -pub fn parse(fh: File) -> Result> { - Ok(parse::grid(parse::raw_lines(fh), |c, _, _| match c { - b'.' => Tile::Floor, - b'S' => Tile::Start, - b'|' => Tile::UpDown, - b'-' => Tile::LeftRight, - b'L' => Tile::UpRight, - b'J' => Tile::UpLeft, - b'F' => Tile::DownRight, - b'7' => Tile::DownLeft, - _ => panic!("bad tile {c}"), - })) -} - -pub fn part1(map: Grid) -> Result { +fn find_loop(map: &Grid) -> (Vec<(Row, Col)>, Tile) { let mut cur = map .indexed_cells() .find_map(|(pos, tile)| { @@ -111,11 +97,84 @@ pub fn part1(map: Grid) -> Result { } } } - Ok(i64::try_from(pipe_loop.len() - 1).unwrap() / 2) + pipe_loop.pop(); + let start_tile = match ( + pipe_loop[0].0.cmp(&pipe_loop[1].0), + pipe_loop[0].1.cmp(&pipe_loop[1].1), + pipe_loop[0].0.cmp(&pipe_loop[pipe_loop.len() - 1].0), + pipe_loop[0].1.cmp(&pipe_loop[pipe_loop.len() - 1].1), + ) { + (Ordering::Less, _, Ordering::Greater, _) + | (Ordering::Greater, _, Ordering::Less, _) => Tile::UpDown, + (_, Ordering::Less, _, Ordering::Greater) + | (_, Ordering::Greater, _, Ordering::Less) => Tile::LeftRight, + (Ordering::Greater, _, _, Ordering::Greater) + | (_, Ordering::Greater, Ordering::Greater, _) => Tile::UpLeft, + (Ordering::Greater, _, _, Ordering::Less) + | (_, Ordering::Less, Ordering::Greater, _) => Tile::UpRight, + (Ordering::Less, _, _, Ordering::Greater) + | (_, Ordering::Greater, Ordering::Less, _) => Tile::DownLeft, + (Ordering::Less, _, _, Ordering::Less) + | (_, Ordering::Less, Ordering::Less, _) => Tile::DownRight, + _ => unreachable!(), + }; + (pipe_loop, start_tile) } -pub fn part2(_: Grid) -> Result { - todo!() +pub fn parse(fh: File) -> Result> { + Ok(parse::grid(parse::raw_lines(fh), |c, _, _| match c { + b'.' => Tile::Floor, + b'S' => Tile::Start, + b'|' => Tile::UpDown, + b'-' => Tile::LeftRight, + b'L' => Tile::UpRight, + b'J' => Tile::UpLeft, + b'F' => Tile::DownRight, + b'7' => Tile::DownLeft, + _ => panic!("bad tile {c}"), + })) +} + +pub fn part1(map: Grid) -> Result { + Ok(i64::try_from(find_loop(&map).0.len()).unwrap() / 2) +} + +pub fn part2(map: Grid) -> Result { + let (pipe_loop, start_tile) = find_loop(&map); + let pipe_loop: HashSet<_> = pipe_loop.into_iter().collect(); + let mut total = 0; + for ((row, col), tile) in map.indexed_cells() { + if pipe_loop.contains(&(row, col)) { + continue; + } + let mut count = 0; + for offset in 0..=(row.0.min(col.0)) { + let check_row = row - offset; + let check_col = col - offset; + if !pipe_loop.contains(&(check_row, check_col)) { + continue; + } + let check_tile = map[check_row][check_col]; + let check_tile = if matches!(check_tile, Tile::Start) { + start_tile + } else { + check_tile + }; + if matches!( + check_tile, + Tile::UpDown + | Tile::LeftRight + | Tile::UpLeft + | Tile::DownRight + ) { + count += 1; + } + } + if count % 2 == 1 { + total += 1; + } + } + Ok(total) } #[test] -- cgit v1.2.3-54-g00ecf