Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 037ab67

Browse files
Year 2024 Day 7
1 parent 61c7596 commit 037ab67

File tree

7 files changed

+131
-0
lines changed

7 files changed

+131
-0
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
| 4 | [Ceres Search](https://adventofcode.com/2024/day/4) | [Source](src/year2024/day04.rs) | 77 |
7979
| 5 | [Print Queue](https://adventofcode.com/2024/day/5) | [Source](src/year2024/day05.rs) | 18 |
8080
| 6 | [Guard Gallivant](https://adventofcode.com/2024/day/6) | [Source](src/year2024/day06.rs) | 386 |
81+
| 7 | [Bridge Repair](https://adventofcode.com/2024/day/7) | [Source](src/year2024/day07.rs) | 220 |
8182

8283
## 2023
8384

‎benches/benchmark.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,4 +298,5 @@ mod year2024 {
298298
benchmark!(year2024, day04);
299299
benchmark!(year2024, day05);
300300
benchmark!(year2024, day06);
301+
benchmark!(year2024, day07);
301302
}

‎src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,4 +297,5 @@ pub mod year2024 {
297297
pub mod day04;
298298
pub mod day05;
299299
pub mod day06;
300+
pub mod day07;
300301
}

‎src/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,5 +367,6 @@ fn year2024() -> Vec<Solution> {
367367
solution!(year2024, day04),
368368
solution!(year2024, day05),
369369
solution!(year2024, day06),
370+
solution!(year2024, day07),
370371
]
371372
}

‎src/year2024/day07.rs

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
//! # Bridge Repair
2+
//!
3+
//! The equations can be validated using a recursive solution that checks all possible combinations
4+
//! of operators. However the number of states to check grows exponentially as 2n in part one
5+
//! and 3n in part two.
6+
//!
7+
//! As much faster approach works in reverse from the end of the equation to prune as many states
8+
//! as possible by checking which operations are possible. For example:
9+
//!
10+
//! ```none
11+
//! Test Value: 123456
12+
//! Equation: 2 617 56
13+
//! Addition is possible as 123456 >= 56
14+
//! Multiplication is not possible as 56 is not a factor of 123456
15+
//! Concatenation is possible as 1234 || 56 = 123456
16+
//! ```
17+
//!
18+
//! Following the concatenation branch and applying an inverse concentation
19+
//! (the full solution would also follow the addition branch):
20+
//!
21+
//! ```none
22+
//! Test Value: 1234
23+
//! Equation: 2 617
24+
//! Addition is possible as 1234 >= 617
25+
//! Multiplication is possible as 2 * 617 = 1234
26+
//! Concatenation is not possible as 1234 does not end in 617
27+
//! ```
28+
//!
29+
//! Following the multiplication branch:
30+
//!
31+
//! ```none
32+
//! Test Value: 2
33+
//! Equation: 2
34+
//! Addition is possible
35+
//! Multiplication is possible
36+
//! Concatenation is possible
37+
//! ```
38+
//!
39+
//! Following the addition or concatentation branches results in a test value of 0 which means
40+
//! that all terms have been applied successfully and the equation is valid.
41+
//!
42+
//! Inverse concenation can be implemented without time consuming conversion to or from
43+
//! strings by dividing the left term by the next power of ten greater than the right term.
44+
//! For example:
45+
//!
46+
//! * 7 || 9 => 79 => 79 / 10 => 7
47+
//! * 12 || 34 => 1234 => 1234 / 100 => 12
48+
//! * 123 || 789 => 123789 => 123789 / 1000 => 123
49+
use crate::util::parse::*;
50+
51+
type Input = (u64, u64);
52+
53+
pub fn parse(input: &str) -> Input {
54+
let mut equation = Vec::new();
55+
let mut part_one = 0;
56+
let mut part_two = 0;
57+
58+
for line in input.lines() {
59+
equation.extend(line.iter_unsigned::<u64>());
60+
61+
// If an equation is valid for part one then it's also valid for part two.
62+
if valid(&equation, equation[0], equation.len() - 1, false) {
63+
part_one += equation[0];
64+
part_two += equation[0];
65+
} else if valid(&equation, equation[0], equation.len() - 1, true) {
66+
part_two += equation[0];
67+
}
68+
69+
equation.clear();
70+
}
71+
72+
(part_one, part_two)
73+
}
74+
75+
pub fn part1(input: &Input) -> u64 {
76+
input.0
77+
}
78+
79+
pub fn part2(input: &Input) -> u64 {
80+
input.1
81+
}
82+
83+
fn valid(terms: &[u64], test_value: u64, index: usize, concat: bool) -> bool {
84+
(test_value == 0)
85+
|| (concat
86+
&& test_value % next_power_of_ten(terms[index]) == terms[index]
87+
&& valid(terms, test_value / next_power_of_ten(terms[index]), index - 1, concat))
88+
|| (test_value % terms[index] == 0
89+
&& valid(terms, test_value / terms[index], index - 1, concat))
90+
|| (test_value >= terms[index]
91+
&& valid(terms, test_value - terms[index], index - 1, concat))
92+
}
93+
94+
fn next_power_of_ten(n: u64) -> u64 {
95+
let mut power = 10;
96+
97+
while power <= n {
98+
power *= 10;
99+
}
100+
101+
power
102+
}

‎tests/test.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,4 +287,5 @@ mod year2024 {
287287
mod day04_test;
288288
mod day05_test;
289289
mod day06_test;
290+
mod day07_test;
290291
}

‎tests/year2024/day07_test.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
use aoc::year2024::day07::*;
2+
3+
const EXAMPLE: &str = "\
4+
190: 10 19
5+
3267: 81 40 27
6+
83: 17 5
7+
156: 15 6
8+
7290: 6 8 6 15
9+
161011: 16 10 13
10+
192: 17 8 14
11+
21037: 9 7 18 13
12+
292: 11 6 16 20";
13+
14+
#[test]
15+
fn part1_test() {
16+
let input = parse(EXAMPLE);
17+
assert_eq!(part1(&input), 3749);
18+
}
19+
20+
#[test]
21+
fn part2_test() {
22+
let input = parse(EXAMPLE);
23+
assert_eq!(part2(&input), 11387);
24+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /