Skip to content

Commit b0e35fc

Browse files
committed
Day 16
1 parent 8a9e758 commit b0e35fc

File tree

2 files changed

+65
-32
lines changed

2 files changed

+65
-32
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ Solutions for [Advent of Code](https://adventofcode.com/) in [Rust](https://www.
2626
| [Day 13](./src/bin/13.rs) | `90.9µs` | `91.8µs` |
2727
| [Day 14](./src/bin/14.rs) | `30.8µs` | `3.5ms` |
2828
| [Day 15](./src/bin/15.rs) | `119.7µs` | `591.0µs` |
29-
| [Day 16](./src/bin/16.rs) | `173.1µs` | `129.8ms` |
29+
| [Day 16](./src/bin/16.rs) | `203.4µs` | `33.3ms` |
3030

31-
**Total: 161.30ms**
31+
**Total: 64.83ms**
3232
<!--- benchmarking table --->
3333

3434
---

src/bin/16.rs

Lines changed: 63 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,17 @@ pub fn part_one(input: &str) -> Option<u64> {
7474
Some(min_cost)
7575
}
7676

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+
7788
pub fn part_two(input: &str) -> Option<u64> {
7889
let (grid, start) = Grid::new_from_str_capture_start(input, &|c| c, &|c| c == 'S');
7990
let target_pos = grid
@@ -108,15 +119,8 @@ pub fn part_two(input: &str) -> Option<u64> {
108119
let mut best_spots_grid = base_false_grid.clone();
109120
let mut best_target_cost = u64::MAX;
110121
let mut best_cost_grid = Grid::new(grid.width, grid.height, [u64::MAX; 4]);
111-
let dir_to_index = |d: Direction| match d {
112-
RIGHT => 0,
113-
DOWN => 1,
114-
LEFT => 2,
115-
UP => 3,
116-
_ => unreachable!(),
117-
};
118122

119-
while let Some(s) = q.pop_front() {
123+
while let Some(mut s) = q.pop_front() {
120124
if s.pos == target_pos {
121125
if best_target_cost < s.cost {
122126
continue;
@@ -139,36 +143,65 @@ pub fn part_two(input: &str) -> Option<u64> {
139143

140144
let right = s.dir.rotate_clockwise();
141145
let left = s.dir.rotate_counterclockwise();
142-
for &(pos, dir, cost) in [
143-
(s.pos + s.dir, s.dir, s.cost + 1),
144-
(s.pos + left, left, s.cost + 1000 + 1),
145-
(s.pos + right, right, s.cost + 1000 + 1),
146-
]
147-
.iter()
148-
{
146+
let is_viable = |&(pos, dir, cost)| {
149147
if grid[pos] == '#' {
150-
continue;
148+
return false;
151149
}
152150
let best_cost_to_next_pos = best_cost_grid[pos][dir_to_index(dir)];
153151
if best_cost_to_next_pos < cost {
154-
continue;
152+
return false;
155153
}
156-
157154
if cost > best_target_cost {
158-
continue;
155+
return false;
159156
}
157+
true
158+
};
160159

161-
let mut new_path = path_pool.pull(|| Vec::with_capacity(1024));
162-
new_path.clear();
163-
new_path.extend(s.path.iter());
164-
new_path.push(pos);
165-
let new_state = State {
166-
path: new_path,
167-
pos,
168-
dir,
169-
cost,
170-
};
171-
q.push_back(new_state);
160+
let all_options = [
161+
(s.pos + s.dir, s.dir, s.cost + 1),
162+
(s.pos + left, left, s.cost + 1000 + 1),
163+
(s.pos + right, right, s.cost + 1000 + 1),
164+
];
165+
166+
let viable_options = [
167+
is_viable(&all_options[0]),
168+
is_viable(&all_options[1]),
169+
is_viable(&all_options[2]),
170+
];
171+
172+
// fast path when there is only one option to avoid copying the path
173+
let viable_count = viable_options.iter().filter(|&&b| b).count();
174+
match viable_count {
175+
0 => continue,
176+
1 => {
177+
let idx = viable_options.iter().position(|&b| b).unwrap();
178+
let (pos, dir, cost) = all_options[idx];
179+
s.path.push(pos);
180+
s.cost = cost;
181+
s.pos = pos;
182+
s.dir = dir;
183+
q.push_back(s);
184+
}
185+
_ => {
186+
for (idx, &is_viable) in viable_options.iter().enumerate() {
187+
if !is_viable {
188+
continue;
189+
}
190+
191+
let (pos, dir, cost) = all_options[idx];
192+
let mut new_path = path_pool.pull(|| Vec::with_capacity(1024));
193+
new_path.clear();
194+
new_path.extend(s.path.iter());
195+
new_path.push(pos);
196+
let new_state = State {
197+
path: new_path,
198+
pos,
199+
dir,
200+
cost,
201+
};
202+
q.push_back(new_state);
203+
}
204+
}
172205
}
173206
}
174207

0 commit comments

Comments
 (0)