From 148112498bd4c89e132c1014c19d19631b6fa537 Mon Sep 17 00:00:00 2001 From: Justin Wernick Date: Thu, 14 Dec 2023 19:37:49 +0200 Subject: Day 10 part 2 --- 2023/src/bin/day_10.rs | 122 ++++++++++++++++++++++--------------------------- 1 file changed, 54 insertions(+), 68 deletions(-) (limited to '2023/src/bin') diff --git a/2023/src/bin/day_10.rs b/2023/src/bin/day_10.rs index 33937b8..84d6327 100644 --- a/2023/src/bin/day_10.rs +++ b/2023/src/bin/day_10.rs @@ -83,41 +83,59 @@ impl Maze { fn count_blocks_inside_the_pipe_loop(&self) -> usize { let mut flood_fill_maze = FloodFillMaze::init_for_maze(&self); + let start_position = self.find_start(); + { - // flood fill the pipe loop - let mut position = self.find_start(); - flood_fill_maze.fill_one(position, FloodFill::Pipe); + // fill the pipe loop + let mut position = start_position; + flood_fill_maze.fill(position, FloodFill::Pipe); let mut facing = self.find_start_facing(position); position = position.go(facing); while self.at(position) != Pipe::Start { - flood_fill_maze.fill_one(position, FloodFill::Pipe); + flood_fill_maze.fill(position, FloodFill::Pipe); facing = self.at(position).exit_facing(facing).unwrap(); position = position.go(facing); } } - let (normal, start_pipe_position) = { - // flood fill from the boundary until I find a pipe loop piece - let mut position = Point { x: 0, y: 0 }; - let mut found_pipes = Vec::new(); - - while found_pipes.len() == 0 { - found_pipes = flood_fill_maze - .fill_flood(position, FloodFill::Outside) - .into_iter() - .filter(|(_, p)| self.at(*p).connections().len() == 2) - .collect(); - position = position.right(); + for y in 0..self.0.len() { + for x in 0..self.0[y].len() { + if flood_fill_maze.0[y][x].is_none() { + let trace_range = if y <= start_position.y { + 0..y + } else { + y + 1..self.0.len() + }; + let mut outside = true; + for trace_y in trace_range { + if flood_fill_maze.0[trace_y][x] == Some(FloodFill::Pipe) + && self + .at(Point { x, y: trace_y }) + .crossed_by_vertical_hanging_right() + { + outside = !outside; + } + } + flood_fill_maze.fill( + Point { x, y }, + if outside { + FloodFill::Outside + } else { + FloodFill::Inside + }, + ); + } } - found_pipes[0] - }; + } - // use this to identify the inner side of the pipe - // trace along the inner side of the pipe, floor filling inside - // count the number of inner fills - todo!() + flood_fill_maze + .0 + .iter() + .flat_map(|row| row.iter()) + .filter(|x| **x == Some(FloodFill::Inside)) + .count() } fn at(&self, p: Point) -> Pipe { @@ -231,6 +249,19 @@ impl Pipe { }, } } + + fn crossed_by_vertical_hanging_right(&self) -> bool { + match self { + Pipe::Start => panic!("Undefined crossing over the start"), + Pipe::Nothing => false, + Pipe::DownLeft => false, + Pipe::DownRight => true, + Pipe::DownUp => false, + Pipe::LeftRight => true, + Pipe::UpLeft => false, + Pipe::UpRight => true, + } + } } impl Point { @@ -282,54 +313,9 @@ impl FloodFillMaze { ) } - fn fill_one(&mut self, point: Point, fill: FloodFill) { - if self.0[point.y][point.x].is_none() { - self.0[point.y][point.x] = Some(fill); - } - } - - /// Returns a list of touched pipes, and the direction they were touched - /// from. - fn fill_flood(&mut self, point: Point, fill: FloodFill) -> Vec<(Direction, Point)> { - let mut pipes = Vec::new(); - + fn fill(&mut self, point: Point, fill: FloodFill) { if self.0[point.y][point.x].is_none() { self.0[point.y][point.x] = Some(fill); - - if point.y > 0 { - let up = point.up(); - if self.0[up.y][up.x] == Some(FloodFill::Pipe) { - pipes.push((Direction::Up, up)); - } else { - pipes.append(&mut self.fill_flood(up, fill)); - } - } - if point.y < self.0.len() - 1 { - let down = point.down(); - if self.0[down.y][down.x] == Some(FloodFill::Pipe) { - pipes.push((Direction::Down, down)); - } else { - pipes.append(&mut self.fill_flood(down, fill)) - } - } - if point.x > 0 { - let left = point.left(); - if self.0[left.y][left.x] == Some(FloodFill::Pipe) { - pipes.push((Direction::Left, left)); - } else { - pipes.append(&mut self.fill_flood(left, fill)) - }; - } - if point.x < self.0[point.y].len() - 1 { - let right = point.right(); - if self.0[right.y][right.x] == Some(FloodFill::Pipe) { - pipes.push((Direction::Right, right)); - } else { - pipes.append(&mut self.fill_flood(right, fill)) - } - } } - - pipes } } -- cgit v1.2.3