summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2023-12-10 14:15:56 -0500
committerJesse Luehrs <doy@tozt.net>2023-12-10 14:15:56 -0500
commit681ef52b88c4b53b86fdc5bf45db19271253b108 (patch)
tree7acc32fc240b40f2ed4576264102eb9c0eed4511
parent9c29b9932d131136b37eb0e3b4a53b4c25a2903a (diff)
downloadadvent-of-code-681ef52b88c4b53b86fdc5bf45db19271253b108.tar.gz
advent-of-code-681ef52b88c4b53b86fdc5bf45db19271253b108.zip
day 10 part 2
-rw-r--r--src/bin/2023/day10.rs95
1 files 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<Grid<Tile>> {
- 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<Tile>) -> Result<i64> {
+fn find_loop(map: &Grid<Tile>) -> (Vec<(Row, Col)>, Tile) {
let mut cur = map
.indexed_cells()
.find_map(|(pos, tile)| {
@@ -111,11 +97,84 @@ pub fn part1(map: Grid<Tile>) -> Result<i64> {
}
}
}
- 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<Tile>) -> Result<i64> {
- todo!()
+pub fn parse(fh: File) -> Result<Grid<Tile>> {
+ 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<Tile>) -> Result<i64> {
+ Ok(i64::try_from(find_loop(&map).0.len()).unwrap() / 2)
+}
+
+pub fn part2(map: Grid<Tile>) -> Result<i64> {
+ 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]