Skip to content

Commit

Permalink
Pathfinding attempt
Browse files Browse the repository at this point in the history
  • Loading branch information
connorslade committed Nov 28, 2023
1 parent b4da6c5 commit 64e14b4
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 7 deletions.
67 changes: 65 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions aoc_2022/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ hashbrown = "0.13.1"
indoc = "2.0.4"
nd_vec = "0.3.0"
num-traits = "0.2.15"
pathfinding = "4.3.3"
petgraph = "0.6.2"
rayon = "1.6.1"
68 changes: 63 additions & 5 deletions aoc_2022/src/day_24.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use common::{Answer, Solution};
use hashbrown::HashSet;
use nd_vec::{vector, Vec2};
use pathfinding::directed::bfs::bfs;

type Pos = Vec2<usize>;

Expand All @@ -12,7 +14,23 @@ impl Solution for Day24 {

fn part_a(&self, input: &str) -> Answer {
let basin = Basin::parse(input);
Answer::Unimplemented
let end = basin.end();
let states = basin.all_states();

let path = bfs(
&(vector!(1, 0), 0),
move |(pos, idx)| {
states[(idx + 1) % states.len()]
.available(*pos)
.iter()
.map(move |x| (*x, *idx))
.collect::<Vec<_>>()
},
|(pos, _)| *pos == end,
)
.unwrap();

path.len().into()
}

fn part_b(&self, _input: &str) -> Answer {
Expand All @@ -28,17 +46,17 @@ enum Direction {
}

// [up, down, left, right]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
struct Blizzard(u8);

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
enum Tile {
Empty,
Wall,
Blizzard(Blizzard),
}

#[derive(Debug)]
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
struct Basin {
tiles: Vec<Vec<Tile>>,
size: Pos,
Expand All @@ -58,6 +76,34 @@ impl Basin {
}
}

fn available(&self, pos: Pos) -> Vec<Pos> {
let mut out = Vec::new();
let [x, y] = [pos.x(), pos.y()];
let [sx, sy] = [self.size.x(), self.size.y()];

if self.tiles[y][x] == Tile::Empty {
out.push(vector!(x, y));
}

if x >= 1 && self.tiles[y][x - 1] == Tile::Empty {
out.push(vector!(x - 1, y));
}

if x + 1 < sx && self.tiles[y][x + 1] == Tile::Empty {
out.push(vector!(x + 1, y));
}

if y + 1 < sy && self.tiles[y + 1][x] == Tile::Empty {
out.push(vector!(x, y + 1));
}

if y >= 1 && self.tiles[y - 1][x] == Tile::Empty {
out.push(vector!(x, y - 1));
}

out
}

fn tick(&self) -> Self {
let mut tiles = vec![vec![Tile::Empty; self.size.x()]; self.size.y()];

Expand All @@ -73,7 +119,7 @@ impl Basin {

let [nx, ny] = [new_pos.x(), new_pos.y()];
if self.tiles[ny][nx] == Tile::Wall {
let [sx, sy] = [self.size.y() - 2, self.size.x() - 2];
let [sx, sy] = [self.size.x() - 2, self.size.y() - 2];
new_pos = match dir {
Direction::Up => vector!(nx, sy),
Direction::Down => vector!(nx, 1),
Expand All @@ -100,6 +146,18 @@ impl Basin {
Self { tiles, ..*self }
}

fn all_states(mut self) -> Vec<Self> {
let mut seen = HashSet::new();
let mut out = Vec::new();

while seen.insert(self.clone()) {
out.push(self.clone());
self = self.tick();
}

out
}

fn end(&self) -> Pos {
vector!(self.size.y() - 1, self.size.x() - 2)
}
Expand Down

0 comments on commit 64e14b4

Please sign in to comment.