Skip to content

Commit b7152e8

Browse files
committed
Day 16
1 parent cc929bc commit b7152e8

File tree

1 file changed

+41
-93
lines changed

1 file changed

+41
-93
lines changed

src/bin/16.rs

Lines changed: 41 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,46 @@
1+
use object_pool::Pool;
12
use std::collections::VecDeque;
23

34
use mygrid::{
45
direction::{Direction, DOWN, LEFT, RIGHT, UP},
56
grid::Grid,
6-
point::Point,
77
};
88

99
advent_of_code::solution!(16);
1010

11+
#[inline]
12+
fn dir_to_index(dir: Direction) -> usize {
13+
match dir {
14+
RIGHT => 0,
15+
DOWN => 1,
16+
LEFT => 2,
17+
UP => 3,
18+
_ => unreachable!(),
19+
}
20+
}
21+
1122
pub fn part_one(input: &str) -> Option<u64> {
1223
let (grid, start) = Grid::new_from_str_capture_start(input, &|c| c, &|c| c == 'S');
13-
let target_pos = grid
14-
.iter_item_and_position()
15-
.filter(|&(_, c)| *c == 'E')
16-
.map(|(p, _)| p)
17-
.next()
18-
.unwrap();
19-
20-
#[derive(Debug, PartialEq, Eq)]
21-
struct State {
22-
pos: Point,
23-
dir: Direction,
24-
cost: u64,
25-
}
24+
let target_pos = grid.find_position_of(&'E').unwrap();
2625

2726
let mut q = VecDeque::new();
28-
q.push_back(State {
29-
pos: start,
30-
dir: RIGHT,
31-
cost: 0,
32-
});
27+
q.push_back((start, RIGHT, 0));
3328

3429
let mut best_cost_grid = Grid::new(grid.width, grid.height, [u64::MAX; 4]);
35-
let dir_to_index = |d: Direction| match d {
36-
RIGHT => 0,
37-
DOWN => 1,
38-
LEFT => 2,
39-
UP => 3,
40-
_ => unreachable!(),
41-
};
4230

43-
while let Some(s) = q.pop_front() {
44-
if s.pos == target_pos {
45-
best_cost_grid[s.pos][dir_to_index(s.dir)] = s.cost;
31+
while let Some((pos, dir, cost)) = q.pop_front() {
32+
if pos == target_pos {
33+
best_cost_grid[pos][dir_to_index(dir)] = cost;
4634
continue;
4735
}
4836

49-
let right = s.dir.rotate_clockwise();
50-
let left = s.dir.rotate_counterclockwise();
37+
let right = dir.rotate_clockwise();
38+
let left = dir.rotate_counterclockwise();
5139

5240
for &(pos, dir, cost) in [
53-
(s.pos + s.dir, s.dir, s.cost + 1),
54-
(s.pos + right, right, s.cost + 1000 + 1),
55-
(s.pos + left, left, s.cost + 1000 + 1),
41+
(pos + dir, dir, cost + 1),
42+
(pos + right, right, cost + 1000 + 1),
43+
(pos + left, left, cost + 1000 + 1),
5644
]
5745
.iter()
5846
{
@@ -65,85 +53,54 @@ pub fn part_one(input: &str) -> Option<u64> {
6553
}
6654
best_cost_grid[pos][dir_to_index(dir)] = cost;
6755

68-
let new_state = State { pos, dir, cost };
69-
q.push_back(new_state);
56+
q.push_back((pos, dir, cost));
7057
}
7158
}
7259

7360
let min_cost = *best_cost_grid[target_pos].iter().min().unwrap();
7461
Some(min_cost)
7562
}
7663

77-
#[inline]
78-
fn dir_to_index(dir: Direction) -> usize {
79-
match dir {
80-
RIGHT => 0,
81-
DOWN => 1,
82-
LEFT => 2,
83-
UP => 3,
84-
_ => unreachable!(),
85-
}
86-
}
87-
8864
pub fn part_two(input: &str) -> Option<u64> {
8965
let (grid, start) = Grid::new_from_str_capture_start(input, &|c| c, &|c| c == 'S');
90-
let target_pos = grid
91-
.iter_item_and_position()
92-
.filter(|&(_, c)| *c == 'E')
93-
.map(|(p, _)| p)
94-
.next()
95-
.unwrap();
96-
97-
use object_pool::{Pool, Reusable};
98-
99-
struct State<'a> {
100-
path: Reusable<'a, Vec<Point>>,
101-
pos: Point,
102-
dir: Direction,
103-
cost: u64,
104-
}
66+
let target_pos = grid.find_position_of(&'E').unwrap();
10567

10668
const PATH_CAPACITY: usize = 512;
10769
let path_pool = Pool::new(256, || Vec::with_capacity(PATH_CAPACITY));
10870
let mut path = path_pool.pull(|| Vec::with_capacity(PATH_CAPACITY));
10971
path.push(start);
11072

11173
let mut q = VecDeque::new();
112-
q.push_back(State {
113-
path,
114-
pos: start,
115-
dir: RIGHT,
116-
cost: 0,
117-
});
74+
q.push_back((path, start, RIGHT, 0));
11875

11976
let base_false_grid = Grid::new(grid.width, grid.height, false);
12077
let mut best_spots_grid = base_false_grid.clone();
12178
let mut best_target_cost = u64::MAX;
12279
let mut best_cost_grid = Grid::new(grid.width, grid.height, [u64::MAX; 4]);
12380

124-
while let Some(mut s) = q.pop_front() {
125-
if s.pos == target_pos {
126-
if best_target_cost < s.cost {
81+
while let Some((mut path, pos, dir, cost)) = q.pop_front() {
82+
if pos == target_pos {
83+
if best_target_cost < cost {
12784
continue;
12885
}
12986

13087
// reset best_spots_grid if we found a better path
131-
if best_target_cost > s.cost {
88+
if best_target_cost > cost {
13289
best_spots_grid = base_false_grid.clone();
13390
}
13491

135-
for &p in s.path.iter() {
92+
for &p in path.iter() {
13693
best_spots_grid[p] = true;
13794
}
13895

139-
best_target_cost = s.cost;
96+
best_target_cost = cost;
14097
continue;
14198
}
14299

143-
best_cost_grid[s.pos][dir_to_index(s.dir)] = s.cost;
100+
best_cost_grid[pos][dir_to_index(dir)] = cost;
144101

145-
let right = s.dir.rotate_clockwise();
146-
let left = s.dir.rotate_counterclockwise();
102+
let right = dir.rotate_clockwise();
103+
let left = dir.rotate_counterclockwise();
147104
let is_viable = |&(pos, dir, cost)| {
148105
if grid[pos] == '#' {
149106
return false;
@@ -159,9 +116,9 @@ pub fn part_two(input: &str) -> Option<u64> {
159116
};
160117

161118
let all_options = [
162-
(s.pos + s.dir, s.dir, s.cost + 1),
163-
(s.pos + left, left, s.cost + 1000 + 1),
164-
(s.pos + right, right, s.cost + 1000 + 1),
119+
(pos + dir, dir, cost + 1),
120+
(pos + left, left, cost + 1000 + 1),
121+
(pos + right, right, cost + 1000 + 1),
165122
];
166123

167124
let viable_options = [
@@ -177,11 +134,8 @@ pub fn part_two(input: &str) -> Option<u64> {
177134
1 => {
178135
let idx = viable_options.iter().position(|&b| b).unwrap();
179136
let (pos, dir, cost) = all_options[idx];
180-
s.path.push(pos);
181-
s.cost = cost;
182-
s.pos = pos;
183-
s.dir = dir;
184-
q.push_back(s);
137+
path.push(pos);
138+
q.push_back((path, pos, dir, cost));
185139
}
186140
_ => viable_options
187141
.iter()
@@ -193,15 +147,9 @@ pub fn part_two(input: &str) -> Option<u64> {
193147

194148
let (pos, dir, cost) = all_options[idx];
195149
let mut new_path = path_pool.pull(|| Vec::with_capacity(PATH_CAPACITY));
196-
new_path.clone_from(&s.path);
150+
new_path.clone_from(&path);
197151
new_path.push(pos);
198-
let new_state = State {
199-
path: new_path,
200-
pos,
201-
dir,
202-
cost,
203-
};
204-
q.push_back(new_state);
152+
q.push_back((new_path, pos, dir, cost));
205153
}),
206154
}
207155
}

0 commit comments

Comments
 (0)