Skip to content

Commit 06a1e7a

Browse files
committed
Day 20 down
1 parent 21bc880 commit 06a1e7a

File tree

5 files changed

+109
-2
lines changed

5 files changed

+109
-2
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Solutions for [Advent of Code](https://adventofcode.com/) in [Rust](https://www.
1010

1111
| Year | Completed |
1212
| :---: | :---: |
13-
| [2024](aoc2024) | 38/50 |
13+
| [2024](aoc2024) | 40/50 |
1414
| [2023](aoc2023) | 50/50 |
1515

1616
---

aoc2024/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ Solutions for [Advent of Code](https://adventofcode.com/) in [Rust](https://www.
2525
| [Day 17](https://adventofcode.com/2024/day/17) | [code](src/bin/17.rs) |||
2626
| [Day 18](https://adventofcode.com/2024/day/18) | [code](src/bin/18.rs) |||
2727
| [Day 19](https://adventofcode.com/2024/day/19) | [code](src/bin/19.rs) |||
28-
| [Day 20](https://adventofcode.com/2024/day/20) | [code](src/bin/20.rs) | _ | _ |
28+
| [Day 20](https://adventofcode.com/2024/day/20) | [code](src/bin/20.rs) | | |
2929
| [Day 21](https://adventofcode.com/2024/day/21) | [code](src/bin/21.rs) | _ | _ |
3030
| [Day 22](https://adventofcode.com/2024/day/22) | [code](src/bin/22.rs) | _ | _ |
3131
| [Day 23](https://adventofcode.com/2024/day/23) | [code](src/bin/23.rs) | _ | _ |

aoc2024/data/examples/20.txt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
###############
2+
#...#...#.....#
3+
#.#.#.#.#.###.#
4+
#S#...#.#.#...#
5+
#######.#.#.###
6+
#######.#.#...#
7+
#######.#.###.#
8+
###..E#...#...#
9+
###.#######.###
10+
#...###...#...#
11+
#.#####.#.###.#
12+
#.#...#.#.#...#
13+
#.#.#.#.#.#.###
14+
#...#...#...###
15+
###############

aoc2024/src/bin/20.rs

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
use std::collections::VecDeque;
2+
3+
use aoc_utils::*;
4+
5+
advent_of_code::solution!(20);
6+
7+
#[cfg(not(test))]
8+
const SAVE_CUTOFF: usize = 100;
9+
#[cfg(test)]
10+
const SAVE_CUTOFF: usize = 50;
11+
12+
fn find_path(start: Point, end: Point, map: &[Vec<char>]) -> Vec<Point> {
13+
let bounds = Bounds(map.len() - 1, map[0].len() - 1);
14+
let seen = &mut vec![vec![false; bounds.1 + 1]; bounds.0 + 1];
15+
seen[start.0][start.1] = true;
16+
let mut queue = VecDeque::new();
17+
let mut path = Vec::new();
18+
queue.push_back(start);
19+
while !queue.is_empty() {
20+
let curr = queue.pop_front().unwrap();
21+
path.push(curr);
22+
if curr == end {
23+
break;
24+
}
25+
Dir::neighbors(curr, bounds).into_iter().for_each(|p| {
26+
if !seen[p.0][p.1] {
27+
seen[p.0][p.1] = true;
28+
if map[p.0][p.1] != '#' {
29+
queue.push_back(p);
30+
}
31+
}
32+
});
33+
}
34+
path
35+
}
36+
37+
fn find_cheats(path: &[Point], max_dist: usize) -> u64 {
38+
path.iter()
39+
.enumerate()
40+
.take(path.len() - SAVE_CUTOFF - 1)
41+
.fold(0, |mut acc, (i, p)| {
42+
path.iter()
43+
.enumerate()
44+
.skip(i + SAVE_CUTOFF + 2)
45+
.for_each(|(j, p2)| {
46+
let d = dist(*p, *p2);
47+
if j - i - d >= SAVE_CUTOFF && d <= max_dist {
48+
acc += 1;
49+
}
50+
});
51+
acc
52+
})
53+
}
54+
55+
pub fn part_one(input: &str) -> Option<u64> {
56+
let map = input.c_map();
57+
let start = find_point(&map, 'S');
58+
let end = find_point(&map, 'E');
59+
let path = find_path(start, end, &map);
60+
Some(find_cheats(&path, 2))
61+
}
62+
63+
pub fn part_two(input: &str) -> Option<u64> {
64+
let map = input.c_map();
65+
let start = find_point(&map, 'S');
66+
let end = find_point(&map, 'E');
67+
let path = find_path(start, end, &map);
68+
Some(find_cheats(&path, 20))
69+
}
70+
71+
#[cfg(test)]
72+
mod tests {
73+
use super::*;
74+
75+
#[test]
76+
fn test_part_one() {
77+
let result = part_one(&advent_of_code::template::read_file("examples", DAY));
78+
assert_eq!(result, Some(1));
79+
}
80+
81+
#[test]
82+
fn test_part_two() {
83+
let result = part_two(&advent_of_code::template::read_file("examples", DAY));
84+
assert_eq!(result, Some(285));
85+
}
86+
}

aoc_utils/src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@ pub enum Dir {
3939
Right,
4040
}
4141

42+
pub fn dist(p: Point, p2: Point) -> usize {
43+
let x = if p.0 > p2.0 { p.0 - p2.0 } else { p2.0 - p.0 };
44+
let y = if p.1 > p2.1 { p.1 - p2.1 } else { p2.1 - p.1 };
45+
x + y
46+
}
47+
4248
impl Dir {
4349
pub fn neighbors(p: Point, b: Bounds) -> ArrayVec<[Point; 4]> {
4450
let mut ns = array_vec!([Point; 4]);

0 commit comments

Comments
 (0)