From 99cb590d6fa24ffc8e454d68d4d68038a98dcb07 Mon Sep 17 00:00:00 2001 From: Matej Focko Date: Sun, 10 Dec 2023 17:45:24 +0100 Subject: [PATCH] day(10): refactor the part 2 Signed-off-by: Matej Focko --- src/bin/day10.rs | 107 ++++++++++++++++++++++++++++------------------- 1 file changed, 64 insertions(+), 43 deletions(-) diff --git a/src/bin/day10.rs b/src/bin/day10.rs index 5f1b0fa..d1e42d2 100644 --- a/src/bin/day10.rs +++ b/src/bin/day10.rs @@ -1,10 +1,44 @@ -use std::{collections::VecDeque, fmt::Display, fmt::Write}; +use std::{ + collections::{HashMap, VecDeque}, + fmt::Display, + fmt::Write, +}; use aoc_2023::*; type Output1 = i32; type Output2 = Output1; +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +enum Direction { + North, + East, + South, + West, +} + +impl Direction { + fn direction_vector(&self) -> Vector2D { + match self { + Direction::North => Vector2D::new(0, -1), + Direction::East => Vector2D::new(1, 0), + Direction::South => Vector2D::new(0, 1), + Direction::West => Vector2D::new(-1, 0), + } + } + + fn state<'a>( + &self, + h: &'a mut HashMap, + v: &'a mut HashMap, + ) -> &'a mut HashMap { + match self { + Direction::North | Direction::South => v, + Direction::East | Direction::West => h, + } + } +} + #[derive(Debug, Clone, Copy, PartialEq, Eq)] enum Tile { Vertical, @@ -18,28 +52,28 @@ enum Tile { } impl Tile { - fn connections(&self) -> Vec> { + fn directions(&self) -> Vec { match self { - Tile::Vertical => vec![Vector2D::new(0, -1), Vector2D::new(0, 1)], - Tile::Horizontal => vec![Vector2D::new(-1, 0), Vector2D::new(1, 0)], - Tile::NorthEast => vec![Vector2D::new(0, -1), Vector2D::new(1, 0)], - Tile::NorthWest => vec![Vector2D::new(0, -1), Vector2D::new(-1, 0)], - Tile::SouthWest => vec![Vector2D::new(-1, 0), Vector2D::new(0, 1)], - Tile::SouthEast => vec![Vector2D::new(0, 1), Vector2D::new(1, 0)], + Tile::Vertical => vec![Direction::North, Direction::South], + Tile::Horizontal => vec![Direction::East, Direction::West], + Tile::NorthEast => vec![Direction::North, Direction::East], + Tile::NorthWest => vec![Direction::North, Direction::West], + Tile::SouthWest => vec![Direction::South, Direction::West], + Tile::SouthEast => vec![Direction::South, Direction::East], Tile::Ground => vec![], Tile::Start => vec![ - Vector2D::new(0, -1), - Vector2D::new(0, 1), - Vector2D::new(-1, 0), - Vector2D::new(1, 0), + Direction::North, + Direction::East, + Direction::South, + Direction::West, ], } } fn next(&self, position: Vector2D) -> Vec> { - self.connections() + self.directions() .iter() - .map(|dv| *dv + position) + .map(|d| d.direction_vector() + position) .collect_vec() } } @@ -174,41 +208,28 @@ impl Solution for Day10 { let mut counter = 0; - let mut horizontally_enclosed_west = vec![false; self.pipes[0].len()]; - let mut horizontally_enclosed_east = vec![false; self.pipes[0].len()]; + let mut horizontal_enclosure: Vec> = + vec![ + HashMap::from([(Direction::West, false), (Direction::East, false)]); + self.pipes[0].len() + ]; for (y, row) in self.pipes.iter().enumerate() { - let mut vertically_enclosed_north = false; - let mut vertically_enclosed_south = false; + let mut vertical_enclosure: HashMap = + HashMap::from([(Direction::North, false), (Direction::South, false)]); + for (x, &t) in row.iter().enumerate() { if self.distances[y][x] != -1 { - if matches!( - t, - Tile::Vertical | Tile::NorthEast | Tile::NorthWest | Tile::Start - ) { - vertically_enclosed_north = !vertically_enclosed_north; - } - if matches!( - t, - Tile::Vertical | Tile::SouthEast | Tile::SouthWest | Tile::Start - ) { - vertically_enclosed_south = !vertically_enclosed_south; - } + for direction in t.directions() { + let directed_state: &mut HashMap = + direction.state(&mut horizontal_enclosure[x], &mut vertical_enclosure); - if matches!( - t, - Tile::Horizontal | Tile::NorthWest | Tile::SouthWest | Tile::Start - ) { - horizontally_enclosed_west[x] = !horizontally_enclosed_west[x]; + if let Some(val) = directed_state.get_mut(&direction) { + *val = !*val; + } } - if matches!( - t, - Tile::Horizontal | Tile::NorthEast | Tile::SouthEast | Tile::Start - ) { - horizontally_enclosed_east[x] = !horizontally_enclosed_east[x]; - } - } else if (vertically_enclosed_north || vertically_enclosed_south) - && (horizontally_enclosed_east[x] || horizontally_enclosed_west[x]) + } else if vertical_enclosure.values().any(|x| *x) + && horizontal_enclosure[x].values().any(|x| *x) { counter += 1; }