day(10): refactor the part 2
Signed-off-by: Matej Focko <mfocko@redhat.com>
This commit is contained in:
parent
f2829381c8
commit
99cb590d6f
1 changed files with 64 additions and 43 deletions
107
src/bin/day10.rs
107
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<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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue