Skip to content

Commit 15739f5

Browse files
committed
Year 2024 Day 18
1 parent 2834fe0 commit 15739f5

File tree

7 files changed

+93
-4
lines changed

7 files changed

+93
-4
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ Performance is reasonable even on older hardware, for example a 2011 MacBook Pro
8989
| 15 | [Warehouse Woes](https://adventofcode.com/2024/day/15) | [Source](src/year2024/day15.rs) | 303 |
9090
| 16 | [Reindeer Maze](https://adventofcode.com/2024/day/16) | [Source](src/year2024/day16.rs) | 390 |
9191
| 17 | [Chronospatial Computer](https://adventofcode.com/2024/day/17) | [Source](src/year2024/day17.rs) | 2 |
92+
| 18 | [RAM Run](https://adventofcode.com/2024/day/18) | [Source](src/year2024/day18.rs) | 61 |
9293

9394
## 2023
9495

benches/benchmark.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,5 +88,5 @@ benchmark!(year2023
8888

8989
benchmark!(year2024
9090
day01, day02, day03, day04, day05, day06, day07, day08, day09, day10, day11, day12, day13,
91-
day14, day15, day16, day17
91+
day14, day15, day16, day17, day18
9292
);

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,5 +68,5 @@ library!(year2023 "Restore global snow production."
6868

6969
library!(year2024 "Locate the Chief Historian in time for the big Christmas sleigh launch."
7070
day01, day02, day03, day04, day05, day06, day07, day08, day09, day10, day11, day12, day13,
71-
day14, day15, day16, day17
71+
day14, day15, day16, day17, day18
7272
);

src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,5 +142,5 @@ run!(year2023
142142

143143
run!(year2024
144144
day01, day02, day03, day04, day05, day06, day07, day08, day09, day10, day11, day12, day13,
145-
day14, day15, day16, day17
145+
day14, day15, day16, day17, day18
146146
);

src/year2024/day18.rs

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
//! # RAM Run
2+
//!
3+
//! We use a trick to speed things up. Instead of storing `#` and `.` in the grid, we store
4+
//! the time when a block arrives. For example:
5+
//!
6+
//! ```none
7+
//! ...#... ∞ ∞ ∞ 3 ∞ ∞ ∞
8+
//! 5,4 ..#.... ∞ ∞ 4 ∞ ∞ ∞ ∞
9+
//! 4,2 ....#.. ∞ ∞ ∞ ∞ 1 ∞ ∞
10+
//! 4,5 => ....... => ∞ ∞ ∞ ∞ ∞ ∞ ∞
11+
//! 3,0 .....#. ∞ ∞ ∞ ∞ ∞ 0 ∞
12+
//! 2,1 ....#.. ∞ ∞ ∞ ∞ 2 ∞ ∞
13+
//! ....... ∞ ∞ ∞ ∞ ∞ ∞ ∞
14+
//! ```
15+
//!
16+
//! Now we can [BFS](https://en.wikipedia.org/wiki/Breadth-first_search) from any arbitrary
17+
//! start time. Squares are blocked only if the grid time is less than or equal to the start time.
18+
//!
19+
//! A [binary search](https://en.wikipedia.org/wiki/Binary_search) is much faster than a
20+
//! linear search with complexity `O(log₂n)` vs `O(n)`. For example `log₂(3450) = 12`.
21+
use crate::util::grid::*;
22+
use crate::util::iter::*;
23+
use crate::util::parse::*;
24+
use crate::util::point::*;
25+
use std::collections::VecDeque;
26+
27+
pub fn parse(input: &str) -> Grid<u16> {
28+
let mut grid = Grid::new(71, 71, u16::MAX);
29+
30+
for (i, [x, y]) in input.iter_signed::<i32>().chunk::<2>().enumerate() {
31+
grid[Point::new(x, y)] = i as u16;
32+
}
33+
34+
grid
35+
}
36+
37+
pub fn part1(grid: &Grid<u16>) -> u32 {
38+
bfs(grid, 1024).unwrap()
39+
}
40+
41+
pub fn part2(grid: &Grid<u16>) -> String {
42+
let mut lower = 0;
43+
let mut upper = 5041;
44+
45+
while lower < upper {
46+
let middle = (lower + upper) / 2;
47+
if bfs(grid, middle).is_some() {
48+
lower = middle + 1;
49+
} else {
50+
upper = middle;
51+
}
52+
}
53+
54+
let index = grid.bytes.iter().position(|&time| time == lower).unwrap() as i32;
55+
format!("{},{}", index % grid.width, index / grid.width)
56+
}
57+
58+
fn bfs(grid: &Grid<u16>, time: u16) -> Option<u32> {
59+
let mut todo = VecDeque::new();
60+
let mut seen = grid.clone();
61+
62+
todo.push_back((ORIGIN, 0));
63+
seen[ORIGIN] = 0;
64+
65+
while let Some((position, cost)) = todo.pop_front() {
66+
if position == Point::new(70, 70) {
67+
return Some(cost);
68+
}
69+
70+
for next in ORTHOGONAL.map(|o| position + o) {
71+
if seen.contains(next) && time < seen[next] {
72+
todo.push_back((next, cost + 1));
73+
seen[next] = 0;
74+
}
75+
}
76+
}
77+
78+
None
79+
}

tests/test.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,5 +81,5 @@ test!(year2023
8181

8282
test!(year2024
8383
day01, day02, day03, day04, day05, day06, day07, day08, day09, day10, day11, day12, day13,
84-
day14, day15, day16, day17
84+
day14, day15, day16, day17, day18
8585
);

tests/year2024/day18.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#[test]
2+
fn part1_test() {
3+
// No test
4+
}
5+
6+
#[test]
7+
fn part2_test() {
8+
// No test
9+
}

0 commit comments

Comments
 (0)