Skip to content

Commit c9fdc18

Browse files
committed
2024 day 10
1 parent 1267349 commit c9fdc18

File tree

3 files changed

+129
-0
lines changed

3 files changed

+129
-0
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
89010123
2+
78121874
3+
87430965
4+
96549874
5+
45678903
6+
32019012
7+
01329801
8+
10456732

crates/year2024/src/day10.rs

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
use utils::grid;
2+
use utils::prelude::*;
3+
4+
/// Counting increasing paths through a grid.
5+
#[derive(Clone, Debug)]
6+
pub struct Day10 {
7+
rows: usize,
8+
cols: usize,
9+
grid: Vec<u32>,
10+
}
11+
12+
impl Day10 {
13+
pub fn new(input: &str, _: InputType) -> Result<Self, InputError> {
14+
let (rows, cols, grid) = grid::from_str(input, |b| match b {
15+
b'0'..=b'9' => Some((b - b'0') as u32),
16+
_ => None,
17+
})?;
18+
19+
Ok(Self { rows, cols, grid })
20+
}
21+
22+
#[must_use]
23+
pub fn part1(&self) -> u32 {
24+
let mut total = 0;
25+
let mut visited = vec![usize::MAX; self.grid.len()];
26+
for r in 0..self.rows {
27+
for c in 0..self.cols {
28+
if self.grid[r * self.cols + c] != 0 {
29+
continue;
30+
}
31+
total += self.trailhead_score(r, c, 1, &mut visited, r * self.cols + c);
32+
}
33+
}
34+
total
35+
}
36+
37+
fn trailhead_score(
38+
&self,
39+
r: usize,
40+
c: usize,
41+
next: u32,
42+
visited: &mut [usize],
43+
visited_key: usize,
44+
) -> u32 {
45+
let index = r * self.cols + c;
46+
visited[index] = visited_key;
47+
if next == 10 {
48+
return 1;
49+
}
50+
51+
let mut total = 0;
52+
if r > 0
53+
&& self.grid[index - self.cols] == next
54+
&& visited[index - self.cols] != visited_key
55+
{
56+
total += self.trailhead_score(r - 1, c, next + 1, visited, visited_key);
57+
}
58+
if r < self.rows - 1
59+
&& self.grid[index + self.cols] == next
60+
&& visited[index + self.cols] != visited_key
61+
{
62+
total += self.trailhead_score(r + 1, c, next + 1, visited, visited_key);
63+
}
64+
if c > 0 && self.grid[index - 1] == next && visited[index - 1] != visited_key {
65+
total += self.trailhead_score(r, c - 1, next + 1, visited, visited_key);
66+
}
67+
if c < self.cols - 1 && self.grid[index + 1] == next && visited[index + 1] != visited_key {
68+
total += self.trailhead_score(r, c + 1, next + 1, visited, visited_key);
69+
}
70+
71+
total
72+
}
73+
74+
pub fn part2(&self) -> u32 {
75+
let mut total = 0;
76+
let mut cache = vec![None; self.grid.len()];
77+
for r in 0..self.rows {
78+
for c in 0..self.cols {
79+
if self.grid[r * self.cols + c] != 0 {
80+
continue;
81+
}
82+
total += self.count_trails(r, c, 1, &mut cache);
83+
}
84+
}
85+
total
86+
}
87+
88+
fn count_trails(&self, r: usize, c: usize, next: u32, cache: &mut [Option<u32>]) -> u32 {
89+
let index = r * self.cols + c;
90+
if let Some(cache) = cache[index] {
91+
return cache;
92+
}
93+
94+
if next == 10 {
95+
cache[index] = Some(1);
96+
return 1;
97+
}
98+
99+
let mut total = 0;
100+
if r > 0 && self.grid[index - self.cols] == next {
101+
total += self.count_trails(r - 1, c, next + 1, cache);
102+
}
103+
if r < self.rows - 1 && self.grid[index + self.cols] == next {
104+
total += self.count_trails(r + 1, c, next + 1, cache);
105+
}
106+
if c > 0 && self.grid[index - 1] == next {
107+
total += self.count_trails(r, c - 1, next + 1, cache);
108+
}
109+
if c < self.cols - 1 && self.grid[index + 1] == next {
110+
total += self.count_trails(r, c + 1, next + 1, cache);
111+
}
112+
113+
cache[index] = Some(total);
114+
total
115+
}
116+
}
117+
118+
examples!(Day10 -> (u32, u32) [
119+
{file: "day10_example0.txt", part1: 36, part2: 81},
120+
]);

crates/year2024/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@ utils::year!(2024 => year2024, ${
1010
6 => day06::Day06,
1111
7 => day07::Day07,
1212
8 => day08::Day08,
13+
10 => day10::Day10,
1314
});

0 commit comments

Comments
 (0)