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::*;
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<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)]
enum Tile {
Vertical,
@ -18,28 +52,28 @@ enum Tile {
}
impl Tile {
fn connections(&self) -> Vec<Vector2D<isize>> {
fn directions(&self) -> Vec<Direction> {
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<isize>) -> Vec<Vector2D<isize>> {
self.connections()
self.directions()
.iter()
.map(|dv| *dv + position)
.map(|d| d.direction_vector() + position)
.collect_vec()
}
}
@ -174,41 +208,28 @@ impl Solution<Output1, Output2> 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<HashMap<Direction, bool>> =
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<Direction, bool> =
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, bool> =
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;
}