Skip to content

Commit f694396

Browse files
committed
Year 2024 Day 20
1 parent 2657df0 commit f694396

File tree

7 files changed

+127
-4
lines changed

7 files changed

+127
-4
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ Performance is reasonable even on older hardware, for example a 2011 MacBook Pro
9191
| 17 | [Chronospatial Computer](https://adventofcode.com/2024/day/17) | [Source](src/year2024/day17.rs) | 2 |
9292
| 18 | [RAM Run](https://adventofcode.com/2024/day/18) | [Source](src/year2024/day18.rs) | 42 |
9393
| 19 | [Linen Layout](https://adventofcode.com/2024/day/19) | [Source](src/year2024/day19.rs) | 118 |
94+
| 20 | [Race Condition](https://adventofcode.com/2024/day/20) | [Source](src/year2024/day20.rs) | 2589 |
9495

9596
## 2023
9697

benches/benchmark.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,5 +88,5 @@ benchmark!(year2023
8888

8989
benchmark!(year2024
9090
day01, day02, day03, day04, day05, day06, day07, day08, day09, day10, day11, day12, day13,
91-
day14, day15, day16, day17, day18, day19
91+
day14, day15, day16, day17, day18, day19, day20
9292
);

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,5 +68,5 @@ library!(year2023 "Restore global snow production."
6868

6969
library!(year2024 "Locate the Chief Historian in time for the big Christmas sleigh launch."
7070
day01, day02, day03, day04, day05, day06, day07, day08, day09, day10, day11, day12, day13,
71-
day14, day15, day16, day17, day18, day19
71+
day14, day15, day16, day17, day18, day19, day20
7272
);

src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,5 +138,5 @@ run!(year2023
138138

139139
run!(year2024
140140
day01, day02, day03, day04, day05, day06, day07, day08, day09, day10, day11, day12, day13,
141-
day14, day15, day16, day17, day18, day19
141+
day14, day15, day16, day17, day18, day19, day20
142142
);

src/year2024/day20.rs

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
//! # Race Condition
2+
use crate::util::grid::*;
3+
use crate::util::point::*;
4+
use crate::util::thread::*;
5+
use std::collections::VecDeque;
6+
use std::sync::atomic::{AtomicU32, Ordering};
7+
8+
pub struct Input {
9+
grid: Grid<u8>,
10+
forward: Grid<i32>,
11+
reverse: Grid<i32>,
12+
full: i32,
13+
}
14+
15+
pub fn parse(input: &str) -> Input {
16+
let grid = Grid::parse(input);
17+
let start = grid.find(b'S').unwrap();
18+
let end = grid.find(b'E').unwrap();
19+
20+
let forward = bfs(&grid, start);
21+
let reverse = bfs(&grid, end);
22+
let full = forward[end];
23+
24+
Input { grid, forward, reverse, full }
25+
}
26+
27+
pub fn part1(input: &Input) -> u32 {
28+
let Input { grid, forward, reverse, full } = input;
29+
let mut total = 0;
30+
31+
for y in 1..grid.height - 1 {
32+
for x in 1..grid.width - 1 {
33+
let first = Point::new(x, y);
34+
35+
if grid[first] != b'#' {
36+
for second in ORTHOGONAL.map(|o| first + o * 2) {
37+
if grid.contains(second) && grid[second] != b'#' {
38+
let cost = forward[first] + reverse[second] + 2;
39+
40+
if *full - cost >= 100 {
41+
total += 1;
42+
}
43+
}
44+
}
45+
}
46+
}
47+
}
48+
49+
total
50+
}
51+
52+
pub fn part2(input: &Input) -> u32 {
53+
let Input { grid, .. } = input;
54+
let mut items = Vec::with_capacity(10_000);
55+
56+
for y in 1..grid.height - 1 {
57+
for x in 1..grid.width - 1 {
58+
let point = Point::new(x, y);
59+
if grid[point] != b'#' {
60+
items.push(point);
61+
}
62+
}
63+
}
64+
65+
let total = AtomicU32::new(0);
66+
spawn_batches(items, |batch| worker(input, &total, batch));
67+
total.into_inner()
68+
}
69+
70+
fn worker(input: &Input, total: &AtomicU32, batch: Vec<Point>) {
71+
let Input { grid, forward, reverse, full } = input;
72+
let mut cheats = 0;
73+
74+
for first in batch {
75+
for y in -20..21_i32 {
76+
for x in (y.abs() - 20)..(21 - y.abs()) {
77+
let second = first + Point::new(x, y);
78+
79+
if grid.contains(second) && grid[second] != b'#' {
80+
let manhattan = x.abs() + y.abs();
81+
let cost = forward[first] + reverse[second] + manhattan;
82+
83+
if *full - cost >= 100 {
84+
cheats += 1;
85+
}
86+
}
87+
}
88+
}
89+
}
90+
91+
total.fetch_add(cheats, Ordering::Relaxed);
92+
}
93+
94+
fn bfs(grid: &Grid<u8>, start: Point) -> Grid<i32> {
95+
let mut todo = VecDeque::new();
96+
let mut seen = grid.same_size_with(i32::MAX);
97+
98+
todo.push_back((start, 0));
99+
seen[start] = 0;
100+
101+
while let Some((position, cost)) = todo.pop_front() {
102+
let cost = cost + 1;
103+
104+
for next in ORTHOGONAL.map(|o| position + o) {
105+
if grid[next] != b'#' && cost < seen[next] {
106+
todo.push_back((next, cost));
107+
seen[next] = cost;
108+
}
109+
}
110+
}
111+
112+
seen
113+
}

tests/test.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,5 +81,5 @@ test!(year2023
8181

8282
test!(year2024
8383
day01, day02, day03, day04, day05, day06, day07, day08, day09, day10, day11, day12, day13,
84-
day14, day15, day16, day17, day18, day19
84+
day14, day15, day16, day17, day18, day19, day20
8585
);

tests/year2024/day20.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#[test]
2+
fn part1_test() {
3+
// No test
4+
}
5+
6+
#[test]
7+
fn part2_test() {
8+
// No test
9+
}

0 commit comments

Comments
 (0)