2023 Day 16 Performance Improvements
This commit is contained in:
parent
bf4577f6e0
commit
89f2b849ad
1 changed files with 33 additions and 8 deletions
|
@ -1,5 +1,5 @@
|
||||||
use core::fmt::Display;
|
use core::fmt::Display;
|
||||||
use std::collections::{HashMap, BTreeSet};
|
use std::collections::{HashMap, BTreeSet, HashSet};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub enum ParseError {
|
pub enum ParseError {
|
||||||
|
@ -16,8 +16,14 @@ impl Display for ParseError {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Eq, Hash)]
|
||||||
|
struct StartingCondition {
|
||||||
|
starting_tile: (usize, usize),
|
||||||
|
starting_direction: Direction,
|
||||||
|
}
|
||||||
|
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
#[derive(PartialEq)]
|
#[derive(PartialEq, Eq, Hash, Clone, Copy)]
|
||||||
enum Direction {
|
enum Direction {
|
||||||
North = 0b0001,
|
North = 0b0001,
|
||||||
West = 0b0010,
|
West = 0b0010,
|
||||||
|
@ -118,7 +124,13 @@ impl TryFrom<&str> for Grid {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Grid {
|
impl Grid {
|
||||||
fn get_energized(&self, starting_tile: (usize, usize), starting_direction: Direction) -> usize {
|
fn get_energized(&self, starting_tile: (usize, usize), starting_direction: Direction, seen: &mut HashSet<StartingCondition>) -> usize {
|
||||||
|
let sc = StartingCondition { starting_tile, starting_direction, };
|
||||||
|
if seen.contains(&sc) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
seen.insert(sc);
|
||||||
|
}
|
||||||
let mut energized: HashMap<(usize, usize), u8> = HashMap::from([(starting_tile, starting_direction.as_u8())]);
|
let mut energized: HashMap<(usize, usize), u8> = HashMap::from([(starting_tile, starting_direction.as_u8())]);
|
||||||
let mut open_set = BTreeSet::from([starting_tile]);
|
let mut open_set = BTreeSet::from([starting_tile]);
|
||||||
while let Some((x, y)) = open_set.pop_last() {
|
while let Some((x, y)) = open_set.pop_last() {
|
||||||
|
@ -148,6 +160,18 @@ impl Grid {
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
if x == 0 && directions.contains(&Direction::West) {
|
||||||
|
seen.insert(StartingCondition{ starting_tile: (x, y), starting_direction: Direction::East });
|
||||||
|
}
|
||||||
|
if y == 0 && directions.contains(&Direction::North) {
|
||||||
|
seen.insert(StartingCondition{ starting_tile: (x, y), starting_direction: Direction::South });
|
||||||
|
}
|
||||||
|
if x == self.max.0 && directions.contains(&Direction::East) {
|
||||||
|
seen.insert(StartingCondition{ starting_tile: (x, y), starting_direction: Direction::West });
|
||||||
|
}
|
||||||
|
if y == self.max.1 && directions.contains(&Direction::South) {
|
||||||
|
seen.insert(StartingCondition{ starting_tile: (x, y), starting_direction: Direction::North });
|
||||||
|
}
|
||||||
for direction in directions {
|
for direction in directions {
|
||||||
if let Some(neighbour) = direction.next_from(x, y) {
|
if let Some(neighbour) = direction.next_from(x, y) {
|
||||||
if neighbour.0 <= self.max.0 && neighbour.1 <= self.max.1 {
|
if neighbour.0 <= self.max.0 && neighbour.1 <= self.max.1 {
|
||||||
|
@ -168,11 +192,12 @@ impl Grid {
|
||||||
|
|
||||||
pub fn run(input: &str) -> Result<(usize, usize), ParseError> {
|
pub fn run(input: &str) -> Result<(usize, usize), ParseError> {
|
||||||
let grid = Grid::try_from(input)?;
|
let grid = Grid::try_from(input)?;
|
||||||
let first = grid.get_energized((0,0), Direction::East);
|
let first = grid.get_energized((0,0), Direction::East, &mut HashSet::new());
|
||||||
let second = (0..grid.max.0).map(|x| grid.get_energized((x, 0), Direction::South)).max().unwrap_or(0).max(
|
let mut seen = HashSet::new();
|
||||||
(0..grid.max.0).map(|x| grid.get_energized((x, grid.max.1), Direction::North)).max().unwrap_or(0).max(
|
let second = (0..grid.max.0).map(|x| grid.get_energized((x, 0), Direction::South, &mut seen)).max().unwrap_or(0).max(
|
||||||
(0..grid.max.1).map(|y| grid.get_energized((0, y), Direction::East)).max().unwrap_or(0).max(
|
(0..grid.max.0).map(|x| grid.get_energized((x, grid.max.1), Direction::North, &mut seen)).max().unwrap_or(0).max(
|
||||||
(0..grid.max.1).map(|y| grid.get_energized((grid.max.0, y), Direction::West)).max().unwrap_or(0)
|
(0..grid.max.1).map(|y| grid.get_energized((0, y), Direction::East, &mut seen)).max().unwrap_or(0).max(
|
||||||
|
(0..grid.max.1).map(|y| grid.get_energized((grid.max.0, y), Direction::West, &mut seen)).max().unwrap_or(0)
|
||||||
)));
|
)));
|
||||||
Ok((first, second))
|
Ok((first, second))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue