summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin Wernick <justin@worthe-it.co.za>2023-12-14 19:37:49 +0200
committerJustin Wernick <justin@worthe-it.co.za>2023-12-14 19:37:49 +0200
commit148112498bd4c89e132c1014c19d19631b6fa537 (patch)
treeb5c41a452ee6bf7561cc9be0ca92c87be9cfb500
parent58bd415c8609ef53eda28cc142101273a704dfb1 (diff)
Day 10 part 2
-rw-r--r--2023/src/bin/day_10.rs122
1 files changed, 54 insertions, 68 deletions
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
}
}