Skip to content

Commit 211d8d6

Browse files
committed
2024: Add solution to Day 10
1 parent 4aff04b commit 211d8d6

File tree

12 files changed

+200
-18
lines changed

12 files changed

+200
-18
lines changed

2024/Cargo.lock

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

2024/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ cargo run --bin day01
1919
7. [Bridge Repair](day07) 🌟🌟
2020
8. [Resonant Collinearity](day08) 🌟🌟
2121
9. [Disk Fragmenter](day09) 🌟🌟
22-
10. [](day10)
22+
10. [Hoof It](day10) 🌟🌟
2323
11. [](day11)
2424
12. [](day12)
2525
13. [](day13)

2024/day10/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ edition = "2021"
66
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
77

88
[dependencies]
9+
lib = { path = "../lib" }

2024/day10/example1.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
0123
2+
1234
3+
8765
4+
9876

2024/day10/example2.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
...0...
2+
...1...
3+
...2...
4+
6543456
5+
7.....7
6+
8.....8
7+
9.....9

2024/day10/example5.txt

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

2024/day10/example6.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.....0.
2+
..4321.
3+
..5..2.
4+
..6543.
5+
..7..4.
6+
..8765.
7+
..9....

2024/day10/example7.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
..90..9
2+
...1.98
3+
...2..7
4+
6543456
5+
765.987
6+
876....
7+
987....

2024/day10/input.txt

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
65456780121098450187634569763232345103213014321223456
2+
56565097632787543296323478890141234234102125630310767
3+
67874198545601612345610165765650105145693496543407898
4+
32923238723432709654326543034789076008786587854343210
5+
41010129610549878723017832129878989019895674963210349
6+
03498034534698965014898901038965432123107895674310478
7+
12567012345787854198743230123453219654256456789321565
8+
01698107659834723085650134562104508723340349876459874
9+
98787238543225610176590121875698698812451210145960123
10+
07456549850110765203485430984788767904322109236871234
11+
12349654763234894312176534983109456765012218347120105
12+
45898763120125234523054325672112309876544367898034876
13+
36765812034576127654369010766043218987432458765565989
14+
29876903107681038923478001897652345898901089014877856
15+
10945789218996987610569123078901236754321198123966987
16+
89032654309345678510787430121230109865120567001855496
17+
70121023498210709425698945230381210778034056532743345
18+
63210110567601812334321876545496321689765123443412210
19+
54216787014503956745430965496587434509894329856301101
20+
09105496923212345866787634987676543213456018763456932
21+
18012387836781078975898523432345232122347890345367873
22+
27601078745896769784309410541230143021038901276216784
23+
34587669654305854693210305670321056523427987689105698
24+
03490548741214903543211234781987897012310094576543567
25+
12321239230903212650106521892016798987454123467612430
26+
12332102107812121786787430752105678901960013438900421
27+
01489237876543080695890124567234787017871012543321530
28+
90574323965012891234301233208943296323702387654487651
29+
87665010121026700343210120112350185410213498703599341
30+
96556901212345619656903234013461234554396569812678210
31+
03467832303434328743874105684570789689487876101432387
32+
12346345694540345012565106799688778776536964566501498
33+
01653210789691236522210239888799669890123453677890567
34+
18764101988780987121329845677234550187652122989108906
35+
89765001877101071030456776540112341290343001010267210
36+
67896982769612132549105689432101032301234578981354310
37+
78767853458743247678014988654312121000225665432458981
38+
69656765432658958976529812763243029810116767898567652
39+
30345899891067867789438701890156710723209852101438943
40+
21230014780890986290105610981260823654367643067324321
41+
10101423634761870121234327876501994569498543458015100
42+
45672344543052765436543234566782987678534412109176211
43+
34985495652143781287430110545093456767623303678989321
44+
43856784743430690398710325432112129865414510510076450
45+
32981012892121589459621234521001036772301623423165569
46+
01670143345023498764560149693456345681066739654234678
47+
12365294256510107643498238782347652397659848765985589
48+
03454385107898212532567345601098701498943707678876432
49+
12763476543789123431052101598709876510232110569845001
50+
29854307630076034521043015691612389323101023454032132
51+
38765218921165087654321126780543432134569878998108941
52+
47894356712234198765230105621234567023878565089237650
53+
21012349803343289890121234310123498012967432176546321

2024/day10/src/main.rs

Lines changed: 106 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,21 @@
22
//! https://adventofcode.com/2024/day/10
33
44
use std::{fs, io};
5+
use std::collections::{BTreeMap, BTreeSet};
56
use std::path::Path;
7+
use lib::vector::Vector;
8+
9+
type Vec2 = Vector<i32, 2>;
10+
11+
const UP: Vec2 = Vec2::new([0, -1]);
12+
const DOWN: Vec2 = Vec2::new([0, 1]);
13+
const LEFT: Vec2 = Vec2::new([-1, 0]);
14+
const RIGHT: Vec2 = Vec2::new([1, 0]);
615

716
fn main() {
8-
let input = Input::from_file(format!("{}/input.txt", env!("CARGO_MANIFEST_DIR"))).expect("failed to read input");
9-
//let input = Input::from_file(format!("{}/example1.txt", env!("CARGO_MANIFEST_DIR"))).expect("failed to read input");
10-
println!("{input:?}");
17+
//let input = Input::from_file(format!("{}/input.txt", env!("CARGO_MANIFEST_DIR"))).expect("failed to read input");
18+
//let input = Input::from_file(format!("{}/example5.txt", env!("CARGO_MANIFEST_DIR"))).expect("failed to read input");
19+
//println!("{input:?}");
1120

1221
// Part 1
1322
println!("Part 1: {}", part1(&input));
@@ -17,24 +26,107 @@ fn main() {
1726
}
1827

1928
fn part1(input: &Input) -> usize {
20-
0
29+
let trailheads: BTreeSet<Vec2> = input.heights.iter()
30+
.filter_map(|(&p, &h)| (h == 0).then_some(p)).collect();
31+
32+
trailheads.into_iter().map(|head| score(head, &input.heights)).sum()
33+
}
34+
35+
fn score(trailhead: Vec2, heights: &BTreeMap<Vec2, u8>) -> usize {
36+
let mut score = 0;
37+
38+
let mut visited: BTreeSet<Vec2> = [trailhead].into_iter().collect();
39+
let mut edge = vec![trailhead];
40+
41+
while let Some(pos) = edge.pop() {
42+
let height = heights[&pos];
43+
44+
if height == 9 {
45+
score += 1;
46+
continue;
47+
}
48+
49+
for dir in [UP, DOWN, LEFT, RIGHT] {
50+
let next_pos = pos + dir;
51+
if visited.contains(&next_pos) {
52+
continue;
53+
}
54+
55+
if heights.get(&next_pos).copied() == Some(height + 1) {
56+
visited.insert(next_pos);
57+
edge.push(next_pos);
58+
}
59+
}
60+
}
61+
62+
score
2163
}
2264

65+
2366
fn part2(input: &Input) -> usize {
24-
0
67+
let trailheads: BTreeSet<Vec2> = input.heights.iter()
68+
.filter_map(|(&p, &h)| (h == 0).then_some(p)).collect();
69+
70+
trailheads.into_iter().map(|head| rating(head, &input.heights)).sum()
71+
}
72+
73+
fn rating(trailhead: Vec2, heights: &BTreeMap<Vec2, u8>) -> usize {
74+
let mut rating = 0;
75+
76+
let mut visited: BTreeSet<Vec<Vec2>> = [vec![trailhead]].into_iter().collect();
77+
let mut edge = vec![vec![trailhead]];
78+
79+
while let Some(trail) = edge.pop() {
80+
let pos = *trail.last().unwrap();
81+
let height = heights[&pos];
82+
if height == 9 {
83+
rating += 1;
84+
continue;
85+
}
86+
87+
for dir in [UP, DOWN, LEFT, RIGHT] {
88+
let next_pos = pos + dir;
89+
let new_trail: Vec<_> = trail.iter().copied().chain([next_pos]).collect();
90+
91+
if visited.contains(&new_trail) {
92+
continue;
93+
}
94+
95+
if heights.get(&next_pos).copied() == Some(height + 1) {
96+
visited.insert(new_trail.clone());
97+
edge.push(new_trail);
98+
}
99+
}
100+
}
101+
102+
rating
25103
}
26104

27105
#[derive(Debug, Clone)]
28106
struct Input {
29-
values: Vec<String>,
107+
heights: BTreeMap<Vec2, u8>,
30108
}
31109

32110
impl Input {
33111
fn from_file(path: impl AsRef<Path>) -> io::Result<Self> {
34112
let input = fs::read_to_string(path)?;
35-
let values = input.lines().map(str::to_string).collect();
36113

37-
Ok(Self { values })
114+
let mut heights = BTreeMap::new();
115+
116+
for (x, line) in input.lines().enumerate() {
117+
for (y, c) in line.trim().chars().enumerate() {
118+
if c == '.' {
119+
continue;
120+
}
121+
122+
let pos = Vec2::new([x as i32, y as i32]);
123+
let height = c.to_digit(10).unwrap() as u8;
124+
125+
heights.insert(pos, height);
126+
}
127+
}
128+
129+
Ok(Self { heights })
38130
}
39131
}
40132

@@ -44,29 +136,29 @@ mod test {
44136

45137
#[test]
46138
fn test_part1() {
47-
let input = Input::from_file("example1.txt").unwrap();
139+
let input = Input::from_file("example5.txt").unwrap();
48140

49-
assert_eq!(part1(&input), 0);
141+
assert_eq!(part1(&input), 36);
50142
}
51143

52144
#[test]
53145
fn test_part1_solution() {
54146
let input = Input::from_file("input.txt").unwrap();
55147

56-
assert_eq!(part1(&input), 0);
148+
assert_eq!(part1(&input), 776);
57149
}
58150

59151
#[test]
60152
fn test_part2() {
61-
let input = Input::from_file("example1.txt").unwrap();
153+
let input = Input::from_file("example5.txt").unwrap();
62154

63-
assert_eq!(part2(&input), 0);
155+
assert_eq!(part2(&input), 81);
64156
}
65157

66158
#[test]
67159
fn test_part2_solution() {
68160
let input = Input::from_file("input.txt").unwrap();
69161

70-
assert_eq!(part2(&input), 0);
162+
assert_eq!(part2(&input), 1657);
71163
}
72164
}

0 commit comments

Comments
 (0)