1
0
Fork 0

day(10): refactor the part 2

Signed-off-by: Matej Focko <mfocko@redhat.com>
This commit is contained in:
Matej Focko 2023-12-10 17:45:24 +01:00
parent f2829381c8
commit 99cb590d6f
Signed by: mfocko
GPG key ID: 7C47D46246790496

View file

@ -1,10 +1,44 @@
use std::{collections::VecDeque, fmt::Display, fmt::Write}; use std::{
collections::{HashMap, VecDeque},
fmt::Display,
fmt::Write,
};
use aoc_2023::*; use aoc_2023::*;
type Output1 = i32; type Output1 = i32;
type Output2 = Output1; type Output2 = Output1;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
enum Direction {
North,
East,
South,
West,
}
impl Direction {
fn direction_vector(&self) -> Vector2D<isize> {
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<Direction, bool>,
v: &'a mut HashMap<Direction, bool>,
) -> &'a mut HashMap<Direction, bool> {
match self {
Direction::North | Direction::South => v,
Direction::East | Direction::West => h,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum Tile { enum Tile {
Vertical, Vertical,
@ -18,28 +52,28 @@ enum Tile {
} }
impl Tile { impl Tile {
fn connections(&self) -> Vec<Vector2D<isize>> { fn directions(&self) -> Vec<Direction> {
match self { match self {
Tile::Vertical => vec![Vector2D::new(0, -1), Vector2D::new(0, 1)], Tile::Vertical => vec![Direction::North, Direction::South],
Tile::Horizontal => vec![Vector2D::new(-1, 0), Vector2D::new(1, 0)], Tile::Horizontal => vec![Direction::East, Direction::West],
Tile::NorthEast => vec![Vector2D::new(0, -1), Vector2D::new(1, 0)], Tile::NorthEast => vec![Direction::North, Direction::East],
Tile::NorthWest => vec![Vector2D::new(0, -1), Vector2D::new(-1, 0)], Tile::NorthWest => vec![Direction::North, Direction::West],
Tile::SouthWest => vec![Vector2D::new(-1, 0), Vector2D::new(0, 1)], Tile::SouthWest => vec![Direction::South, Direction::West],
Tile::SouthEast => vec![Vector2D::new(0, 1), Vector2D::new(1, 0)], Tile::SouthEast => vec![Direction::South, Direction::East],
Tile::Ground => vec![], Tile::Ground => vec![],
Tile::Start => vec![ Tile::Start => vec![
Vector2D::new(0, -1), Direction::North,
Vector2D::new(0, 1), Direction::East,
Vector2D::new(-1, 0), Direction::South,
Vector2D::new(1, 0), Direction::West,
], ],
} }
} }
fn next(&self, position: Vector2D<isize>) -> Vec<Vector2D<isize>> { fn next(&self, position: Vector2D<isize>) -> Vec<Vector2D<isize>> {
self.connections() self.directions()
.iter() .iter()
.map(|dv| *dv + position) .map(|d| d.direction_vector() + position)
.collect_vec() .collect_vec()
} }
} }
@ -174,41 +208,28 @@ impl Solution<Output1, Output2> for Day10 {
let mut counter = 0; let mut counter = 0;
let mut horizontally_enclosed_west = vec![false; self.pipes[0].len()]; let mut horizontal_enclosure: Vec<HashMap<Direction, bool>> =
let mut horizontally_enclosed_east = vec![false; self.pipes[0].len()]; vec![
HashMap::from([(Direction::West, false), (Direction::East, false)]);
self.pipes[0].len()
];
for (y, row) in self.pipes.iter().enumerate() { for (y, row) in self.pipes.iter().enumerate() {
let mut vertically_enclosed_north = false; let mut vertical_enclosure: HashMap<Direction, bool> =
let mut vertically_enclosed_south = false; HashMap::from([(Direction::North, false), (Direction::South, false)]);
for (x, &t) in row.iter().enumerate() { for (x, &t) in row.iter().enumerate() {
if self.distances[y][x] != -1 { if self.distances[y][x] != -1 {
if matches!( for direction in t.directions() {
t, let directed_state: &mut HashMap<Direction, bool> =
Tile::Vertical | Tile::NorthEast | Tile::NorthWest | Tile::Start direction.state(&mut horizontal_enclosure[x], &mut vertical_enclosure);
) {
vertically_enclosed_north = !vertically_enclosed_north;
}
if matches!(
t,
Tile::Vertical | Tile::SouthEast | Tile::SouthWest | Tile::Start
) {
vertically_enclosed_south = !vertically_enclosed_south;
}
if matches!( if let Some(val) = directed_state.get_mut(&direction) {
t, *val = !*val;
Tile::Horizontal | Tile::NorthWest | Tile::SouthWest | Tile::Start }
) {
horizontally_enclosed_west[x] = !horizontally_enclosed_west[x];
} }
if matches!( } else if vertical_enclosure.values().any(|x| *x)
t, && horizontal_enclosure[x].values().any(|x| *x)
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])
{ {
counter += 1; counter += 1;
} }