Skip to content

Commit 247b104

Browse files
committed
Year 2024 Day 2
1 parent ddfe0bf commit 247b104

File tree

7 files changed

+111
-1
lines changed

7 files changed

+111
-1
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ Performance is reasonable even on older hardware, for example a 2011 MacBook Pro
7878
| Day | Problem | Solution | Benchmark (μs) |
7979
| --- | --- | --- | --: |
8080
| 1 | [Historian Hysteria](https://adventofcode.com/2024/day/1) | [Source](src/year2024/day01.rs) | 21 |
81+
| 2 | [Red-Nosed Reports](https://adventofcode.com/2024/day/2) | [Source](src/year2024/day02.rs) | 43 |
8182

8283
## 2023
8384

benches/benchmark.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,4 +293,5 @@ mod year2023 {
293293

294294
mod year2024 {
295295
benchmark!(year2024, day01);
296+
benchmark!(year2024, day02);
296297
}

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,4 +292,5 @@ pub mod year2023 {
292292
/// # Locate the Chief Historian in time for the big Christmas sleigh launch.
293293
pub mod year2024 {
294294
pub mod day01;
295+
pub mod day02;
295296
}

src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -360,5 +360,5 @@ fn year2023() -> Vec<Solution> {
360360
}
361361

362362
fn year2024() -> Vec<Solution> {
363-
vec![solution!(year2024, day01)]
363+
vec![solution!(year2024, day01), solution!(year2024, day02)]
364364
}

src/year2024/day02.rs

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
//! # Red-Nosed Reports
2+
//!
3+
//! Computes boths parts simultaneously. Each pair of levels is converted into deltas of
4+
//! either +1, -1 or 0. For example:
5+
//!
6+
//! * `1 3 6 7 9` => `+1 +1 +1 +1`
7+
//! * `9 7 6 2 1` => `-1 -1 0 -1`
8+
//!
9+
//! If the sum of all delta equals ±4, then we know that all levels are increasing or
10+
//! decreasing. Any other value indicates either mixed up and down transitions or levels that
11+
//! are too far apart.
12+
//!
13+
//! For part two we remove each pair of deltas (or single delta at each end) then replace with
14+
//! the sum of the delta from the new neighbors on either side.
15+
use crate::util::parse::*;
16+
17+
type Input = (u32, u32);
18+
19+
/// Minimize allocation to only a single `vec` reused for each report.
20+
pub fn parse(input: &str) -> Input {
21+
let mut report = Vec::new();
22+
let mut part_one = 0;
23+
let mut part_two = 0;
24+
25+
for line in input.lines() {
26+
report.extend(line.iter_signed::<i32>());
27+
28+
let (p1, p2) = check(&report);
29+
part_one += p1;
30+
part_two += p2;
31+
32+
report.clear();
33+
}
34+
35+
(part_one, part_two)
36+
}
37+
38+
pub fn part1(input: &Input) -> u32 {
39+
input.0
40+
}
41+
42+
pub fn part2(input: &Input) -> u32 {
43+
input.1
44+
}
45+
46+
fn check(report: &[i32]) -> (u32, u32) {
47+
let size = report.len();
48+
let score: i32 = (1..size).map(|i| delta(report[i - 1], report[i])).sum();
49+
50+
if score.abs() == (size - 1) as i32 {
51+
return (1, 1);
52+
}
53+
54+
for i in 0..size {
55+
let mut score = score;
56+
57+
// Snip out each level and replace with new level computed from neighbors to either side.
58+
if i > 0 {
59+
score -= delta(report[i - 1], report[i]);
60+
}
61+
if i < size - 1 {
62+
score -= delta(report[i], report[i + 1]);
63+
}
64+
if i > 0 && i < size - 1 {
65+
score += delta(report[i - 1], report[i + 1]);
66+
}
67+
68+
if score.abs() == (size - 2) as i32 {
69+
return (0, 1);
70+
}
71+
}
72+
73+
(0, 0)
74+
}
75+
76+
/// Convert each pair of levels to either +1 for increase, -1 for decrease or 0 for invalid range.
77+
fn delta(a: i32, b: i32) -> i32 {
78+
let diff = b - a;
79+
80+
if diff.abs() <= 3 {
81+
diff.signum()
82+
} else {
83+
0
84+
}
85+
}

tests/test.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,4 +282,5 @@ mod year2023 {
282282

283283
mod year2024 {
284284
mod day01_test;
285+
mod day02_test;
285286
}

tests/year2024/day02_test.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
use aoc::year2024::day02::*;
2+
3+
const EXAMPLE: &str = "\
4+
7 6 4 2 1
5+
1 2 7 8 9
6+
9 7 6 2 1
7+
1 3 2 4 5
8+
8 6 4 4 1
9+
1 3 6 7 9";
10+
11+
#[test]
12+
fn part1_test() {
13+
let input = parse(EXAMPLE);
14+
assert_eq!(part1(&input), 2);
15+
}
16+
17+
#[test]
18+
fn part2_test() {
19+
let input = parse(EXAMPLE);
20+
assert_eq!(part2(&input), 4);
21+
}

0 commit comments

Comments
 (0)