Skip to content

Commit e685d36

Browse files
committed
2024 day 18
1 parent ef92df2 commit e685d36

File tree

2 files changed

+85
-0
lines changed

2 files changed

+85
-0
lines changed

crates/year2024/src/day18.rs

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
use std::collections::VecDeque;
2+
use utils::point::Point2D;
3+
use utils::prelude::*;
4+
5+
/// Finding when a path through a grid is blocked.
6+
#[derive(Clone, Debug)]
7+
pub struct Day18 {
8+
positions: Vec<Point2D<usize>>,
9+
}
10+
11+
impl Day18 {
12+
pub fn new(input: &str, _: InputType) -> Result<Self, InputError> {
13+
Ok(Self {
14+
positions: parser::number_range(0u32..=70)
15+
.repeat_n(",")
16+
.map(|[x, y]| Point2D {
17+
x: x as usize,
18+
y: y as usize,
19+
})
20+
.parse_lines(input)?,
21+
})
22+
}
23+
24+
#[must_use]
25+
pub fn part1(&self) -> u32 {
26+
self.minimum_steps(1024).expect("no solution found")
27+
}
28+
29+
#[must_use]
30+
pub fn part2(&self) -> String {
31+
let mut left = 0;
32+
let mut right = self.positions.len();
33+
34+
while left < right {
35+
let mid = (left + right) / 2;
36+
match self.minimum_steps(mid + 1) {
37+
Some(_) => left = mid + 1,
38+
None => right = mid,
39+
}
40+
}
41+
42+
if left >= self.positions.len() {
43+
panic!("no solution found");
44+
}
45+
46+
format!("{},{}", self.positions[left].x, self.positions[left].y)
47+
}
48+
49+
fn minimum_steps(&self, fallen: usize) -> Option<u32> {
50+
let mut blocked = [[false; 71]; 71];
51+
for pos in self.positions.iter().take(fallen) {
52+
blocked[pos.x][pos.y] = true;
53+
}
54+
55+
let mut queue = VecDeque::new();
56+
queue.push_back((Point2D::new(0, 0), 0));
57+
58+
while let Some((pos, steps)) = queue.pop_front() {
59+
if pos == Point2D::new(70, 70) {
60+
return Some(steps);
61+
}
62+
if pos.x > 0 && !blocked[pos.x - 1][pos.y] {
63+
queue.push_back((Point2D::new(pos.x - 1, pos.y), steps + 1));
64+
blocked[pos.x - 1][pos.y] = true;
65+
}
66+
if pos.x < 70 && !blocked[pos.x + 1][pos.y] {
67+
queue.push_back((Point2D::new(pos.x + 1, pos.y), steps + 1));
68+
blocked[pos.x + 1][pos.y] = true;
69+
}
70+
if pos.y > 0 && !blocked[pos.x][pos.y - 1] {
71+
queue.push_back((Point2D::new(pos.x, pos.y - 1), steps + 1));
72+
blocked[pos.x][pos.y - 1] = true;
73+
}
74+
if pos.y < 70 && !blocked[pos.x][pos.y + 1] {
75+
queue.push_back((Point2D::new(pos.x, pos.y + 1), steps + 1));
76+
blocked[pos.x][pos.y + 1] = true;
77+
}
78+
}
79+
80+
None
81+
}
82+
}
83+
84+
examples!(Day18 -> (u32, &'static str) []);

crates/year2024/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,5 @@ utils::year!(2024 => year2024, ${
1919
15 => day15::Day15<'_>,
2020
16 => day16::Day16,
2121
17 => day17::Day17,
22+
18 => day18::Day18,
2223
});

0 commit comments

Comments
 (0)