Skip to content

Commit 17c17d3

Browse files
committed
18th day (find_shortest_path_cost optimization)
1 parent 632f10a commit 17c17d3

File tree

2 files changed

+35
-39
lines changed

2 files changed

+35
-39
lines changed

data/examples/18.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,4 @@
2424
1,6
2525
2,0
2626

27-
7,7,12
27+
EXAMPLE: 7,7,12

src/bin/18.rs

Lines changed: 34 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
advent_of_code::solution!(18);
22

3-
use std::collections::VecDeque;
4-
53
use advent_of_code::maneatingape::grid::*;
6-
use advent_of_code::maneatingape::hash::*;
74
use advent_of_code::maneatingape::iter::*;
85
use advent_of_code::maneatingape::parse::*;
96
use advent_of_code::maneatingape::point::*;
@@ -15,7 +12,11 @@ enum Block {
1512
}
1613

1714
fn parse_data(input: &str) -> (Vec<Point>, i32, i32, usize) {
18-
let default_right = format!("{},{},{}", 71, 71, 1024);
15+
const DEFAULT_WIDTH: usize = 71;
16+
const DEFAULT_HEIGHT: usize = 71;
17+
const DEFAULT_FIRST_TAKE: usize = 1024;
18+
19+
let default_right = format!("{DEFAULT_WIDTH},{DEFAULT_HEIGHT},{DEFAULT_FIRST_TAKE}",);
1920
let (left, right) = input.split_once("\n\n").unwrap_or((input, &default_right));
2021

2122
let data = left
@@ -29,44 +30,38 @@ fn parse_data(input: &str) -> (Vec<Point>, i32, i32, usize) {
2930
(data, width, height, first_take as usize)
3031
}
3132

32-
fn neighbors(grid: &Grid<Block>, position: Point, cost: u32) -> Vec<(Point, u32)> {
33-
let mut result = Vec::with_capacity(4);
34-
35-
for direction in [LEFT, RIGHT, UP, DOWN] {
36-
let n_position = position + direction;
37-
38-
if grid.contains(n_position) && matches!(grid[n_position], Block::Ok) {
39-
result.push((n_position, cost + 1));
40-
}
41-
}
42-
43-
result
44-
}
45-
46-
fn find_shortest_path_cost(grid: &Grid<Block>) -> u32 {
33+
fn find_shortest_path_cost(grid: &Grid<Block>) -> Option<u32> {
4734
let start_position = Point::new(0, 0);
4835
let end_position = Point::new(grid.width - 1, grid.height - 1);
4936

50-
let mut queue = VecDeque::new();
51-
let mut g_score = FastMap::new();
37+
let mut queue = std::collections::VecDeque::new();
38+
let mut seen = Grid {
39+
width: grid.width,
40+
height: grid.height,
41+
bytes: vec![false; (grid.width * grid.height) as usize],
42+
};
5243

53-
queue.push_front((0, start_position));
54-
g_score.insert(start_position, 0);
44+
queue.push_front((start_position, 0));
45+
seen[start_position] = true;
5546

56-
while let Some((cost, position)) = queue.pop_front() {
47+
while let Some((position, cost)) = queue.pop_front() {
5748
if position == end_position {
58-
return cost;
49+
return Some(cost);
5950
}
6051

61-
for (n_position, n_cost) in neighbors(grid, position, cost) {
62-
if n_cost < *g_score.get(&n_position).unwrap_or(&u32::MAX) {
63-
g_score.insert(n_position, n_cost);
64-
queue.push_back((n_cost, n_position));
52+
for n_position in ORTHOGONAL.map(|o| position + o) {
53+
if !grid.contains(n_position) || matches!(grid[n_position], Block::Corrupted) {
54+
continue;
55+
}
56+
57+
if !seen[n_position] {
58+
queue.push_back((n_position, cost + 1));
59+
seen[n_position] = true;
6560
}
6661
}
6762
}
6863

69-
u32::MAX
64+
None
7065
}
7166

7267
fn generate_grid(data: &[Point], width: i32, height: i32, n: usize) -> Grid<Block> {
@@ -86,7 +81,7 @@ fn generate_grid(data: &[Point], width: i32, height: i32, n: usize) -> Grid<Bloc
8681
pub fn part_one(input: &str) -> Option<u32> {
8782
let (data, width, height, first_take) = parse_data(input);
8883

89-
let result = find_shortest_path_cost(&generate_grid(&data, width, height, first_take));
84+
let result = find_shortest_path_cost(&generate_grid(&data, width, height, first_take))?;
9085

9186
Some(result)
9287
}
@@ -95,15 +90,14 @@ pub fn part_two(input: &str) -> Option<String> {
9590
let (data, width, height, first_take) = parse_data(input);
9691

9792
let mut a = first_take;
98-
let mut b = input.lines().count();
93+
let mut b = data.len();
9994
while (b - a) > 1 {
10095
let c = (a + b) / 2;
10196

102-
let result = find_shortest_path_cost(&generate_grid(&data, width, height, c));
103-
if result == u32::MAX {
104-
b = c;
105-
} else {
97+
if find_shortest_path_cost(&generate_grid(&data, width, height, c)).is_some() {
10698
a = c;
99+
} else {
100+
b = c;
107101
}
108102
}
109103

@@ -118,13 +112,15 @@ mod tests {
118112

119113
#[test]
120114
fn test_part_one() {
121-
let result = part_one(&advent_of_code::template::read_file("examples", DAY));
115+
let input = advent_of_code::template::read_file("examples", DAY);
116+
let result = part_one(&input);
122117
assert_eq!(result, Some(22));
123118
}
124119

125120
#[test]
126121
fn test_part_two() {
127-
let result = part_two(&advent_of_code::template::read_file("examples", DAY));
122+
let input = advent_of_code::template::read_file("examples", DAY);
123+
let result = part_two(&input);
128124
assert_eq!(result, Some(String::from("6,1")));
129125
}
130126
}

0 commit comments

Comments
 (0)