Skip to content

Commit b92af35

Browse files
committed
add day10
1 parent f2450bb commit b92af35

File tree

3 files changed

+128
-0
lines changed

3 files changed

+128
-0
lines changed

2024/day10/.gitignore

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
input.txt
2+
flamegraph.svg
3+
perf.data*
4+
### Rust
5+
# Generated by Cargo
6+
# will have compiled files and executables
7+
debug/
8+
target/
9+
10+
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
11+
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
12+
Cargo.lock
13+
14+
# These are backup files generated by rustfmt
15+
**/*.rs.bk
16+
17+
# MSVC Windows builds of rustc generate these, which store debugging information
18+
*.pdb
19+

2024/day10/Cargo.toml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[package]
2+
name = "day10"
3+
authors = ["mirsella <[email protected]>"]
4+
version = "0.1.0"
5+
edition = "2021"
6+
7+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8+
9+
[dependencies]
10+
regex = { workspace = true }
11+
itertools = { workspace = true }
12+
pathfinding = { workspace = true }
13+
rayon = { workspace = true }
14+
indexmap = { workspace = true }

2024/day10/src/main.rs

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
use pathfinding::matrix::Matrix;
2+
use std::collections::{HashMap, HashSet};
3+
4+
fn part1(input: &str) -> usize {
5+
let m = Matrix::from_rows(
6+
input
7+
.lines()
8+
.map(|l| l.chars().map(|c| c.to_digit(10).unwrap() as u8)),
9+
)
10+
.unwrap();
11+
fn parkour(m: &Matrix<u8>, trailends: &mut HashSet<(usize, usize)>, pos: (usize, usize)) {
12+
if m[pos] == 9 {
13+
trailends.insert(pos);
14+
return;
15+
}
16+
for neighbor in m.neighbours(pos, false) {
17+
if m[neighbor] == m[pos] + 1 {
18+
parkour(m, trailends, neighbor);
19+
}
20+
}
21+
}
22+
let mut trailheads = HashMap::new();
23+
let mut tmp_trailends = HashSet::new();
24+
for (pos, &char) in m.items() {
25+
if char != 0 {
26+
continue;
27+
}
28+
parkour(&m, &mut tmp_trailends, pos);
29+
trailheads.insert(pos, tmp_trailends.len());
30+
tmp_trailends.clear();
31+
}
32+
trailheads.values().sum()
33+
}
34+
fn part2(input: &str) -> usize {
35+
let m = Matrix::from_rows(
36+
input
37+
.lines()
38+
.map(|l| l.chars().map(|c| c.to_digit(10).unwrap() as u8)),
39+
)
40+
.unwrap();
41+
fn parkour(
42+
m: &Matrix<u8>,
43+
trailends: &mut HashSet<Vec<(usize, usize)>>,
44+
mut current: Vec<(usize, usize)>,
45+
pos: (usize, usize),
46+
) {
47+
current.push(pos);
48+
if m[pos] == 9 {
49+
trailends.insert(current);
50+
return;
51+
}
52+
for neighbor in m.neighbours(pos, false) {
53+
if m[neighbor] == m[pos] + 1 {
54+
parkour(m, trailends, current.clone(), neighbor);
55+
}
56+
}
57+
}
58+
let mut trailheads = HashMap::new();
59+
let mut tmp_trailends = HashSet::new();
60+
for (pos, &char) in m.items() {
61+
if char != 0 {
62+
continue;
63+
}
64+
parkour(&m, &mut tmp_trailends, Vec::new(), pos);
65+
trailheads.insert(pos, tmp_trailends.len());
66+
tmp_trailends.clear();
67+
}
68+
trailheads.values().sum()
69+
}
70+
71+
fn main() {
72+
let input = include_str!("../input.txt");
73+
println!("Part 1: {}", part1(input));
74+
println!("Part 2: {}", part2(input));
75+
}
76+
77+
#[cfg(test)]
78+
mod tests {
79+
const INPUT: &str = "89010123
80+
78121874
81+
87430965
82+
96549874
83+
45678903
84+
32019012
85+
01329801
86+
10456732";
87+
#[test]
88+
fn part1() {
89+
assert_eq!(super::part1(INPUT), 36);
90+
}
91+
#[test]
92+
fn part2() {
93+
assert_eq!(super::part2(INPUT), 81);
94+
}
95+
}

0 commit comments

Comments
 (0)