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
105
src/bin/day10.rs
105
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::*;
|
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!(
|
|
||||||
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)
|
} else if vertical_enclosure.values().any(|x| *x)
|
||||||
&& (horizontally_enclosed_east[x] || horizontally_enclosed_west[x])
|
&& horizontal_enclosure[x].values().any(|x| *x)
|
||||||
{
|
{
|
||||||
counter += 1;
|
counter += 1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue