Skip to content

Commit e8f80ac

Browse files
committed
Working version for Problem 7 part 2 of AOC2024
1 parent 83c277f commit e8f80ac

File tree

1 file changed

+79
-21
lines changed

1 file changed

+79
-21
lines changed

aoc07/src/main.rs

+79-21
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ fn get_input(filename: &str) -> Vec<String> {
1717
enum Operation {
1818
Add,
1919
Mul,
20+
Cat,
2021
}
2122

2223
struct Equation {
@@ -29,8 +30,11 @@ fn read_equations(lines: &[String]) -> Vec<Equation> {
2930
for line in lines {
3031
let (lhs, rhs) = line.split_once(": ").unwrap();
3132
let result = lhs.parse::<usize>().unwrap();
32-
let operands = rhs.split_ascii_whitespace().map(|o| o.parse::<usize>().unwrap()).collect::<Vec<_>>();
33-
let eq = Equation {result, operands};
33+
let operands = rhs
34+
.split_ascii_whitespace()
35+
.map(|o| o.parse::<usize>().unwrap())
36+
.collect::<Vec<_>>();
37+
let eq = Equation { result, operands };
3438
equations.push(eq);
3539
}
3640

@@ -42,19 +46,30 @@ fn read_equations(lines: &[String]) -> Vec<Equation> {
4246
// operands - the immutable list of operands
4347
// operation_index - where we currently are working
4448
// operation - the add/mul we should apply
45-
fn try_operation(target: usize, result: usize, operands: &Vec<usize>, operation_index: usize, operation: Operation) -> bool {
46-
if result > target {
49+
fn try_operation(
50+
target: usize,
51+
result: usize,
52+
operands: &Vec<usize>,
53+
operation_index: usize,
54+
operation: Operation,
55+
cat_supported: bool,
56+
) -> bool {
57+
if result > target || (!cat_supported && operation == Operation::Cat) {
4758
return false;
4859
}
4960

5061
// Perform the operation
5162
let new_result = match operation {
52-
Operation::Add => {
53-
result + operands[operation_index + 1]
54-
},
55-
Operation::Mul => {
56-
result * operands[operation_index + 1]
57-
},
63+
Operation::Add => result + operands[operation_index + 1],
64+
Operation::Mul => result * operands[operation_index + 1],
65+
Operation::Cat => {
66+
// Just convert with a format string and count the digits to multiply by 10
67+
let rhs = operands[operation_index + 1];
68+
let num_digits = format!("{}", rhs);
69+
let mut result = result;
70+
(0..num_digits.len()).for_each(|_| result *= 10);
71+
result + rhs
72+
}
5873
};
5974

6075
if operation_index + 2 == operands.len() {
@@ -66,33 +81,62 @@ fn try_operation(target: usize, result: usize, operands: &Vec<usize>, operation_
6681
}
6782

6883
// Try add and then try multiply recursively
69-
if try_operation(target, new_result, operands, operation_index + 1, Operation::Add) {
84+
if try_operation(
85+
target,
86+
new_result,
87+
operands,
88+
operation_index + 1,
89+
Operation::Add,
90+
cat_supported,
91+
) {
92+
return true;
93+
}
94+
if try_operation(
95+
target,
96+
new_result,
97+
operands,
98+
operation_index + 1,
99+
Operation::Mul,
100+
cat_supported,
101+
) {
70102
return true;
71103
}
72-
if try_operation(target, new_result, operands, operation_index + 1, Operation::Mul) {
104+
if cat_supported
105+
&& try_operation(
106+
target,
107+
new_result,
108+
operands,
109+
operation_index + 1,
110+
Operation::Cat,
111+
cat_supported,
112+
)
113+
{
73114
return true;
74115
}
75116
}
76117
false
77118
}
78119

79-
fn calibrate(equation: &Equation) -> bool {
120+
fn calibrate(equation: &Equation, cat_supported: bool) -> bool {
80121
let target = equation.result;
81122
let operands = &equation.operands;
82123
let result = operands[0];
83-
if try_operation(target, result, operands, 0, Operation::Add) {
124+
if try_operation(target, result, operands, 0, Operation::Add, cat_supported) {
125+
return true;
126+
}
127+
if try_operation(target, result, operands, 0, Operation::Mul, cat_supported) {
84128
return true;
85129
}
86-
if try_operation(target, result, operands, 0, Operation::Mul) {
130+
if cat_supported && try_operation(target, result, operands, 0, Operation::Cat, cat_supported) {
87131
return true;
88132
}
89133
false
90134
}
91135

92-
fn calibrate_all(equations: &Vec<Equation>) -> usize {
136+
fn calibrate_all(equations: &Vec<Equation>, cat_supported: bool) -> usize {
93137
let mut sum = 0;
94138
for equation in equations {
95-
if calibrate(equation) {
139+
if calibrate(equation, cat_supported) {
96140
sum += equation.result;
97141
}
98142
}
@@ -103,17 +147,31 @@ fn calibrate_all(equations: &Vec<Equation>) -> usize {
103147

104148
#[test]
105149
fn test_prelim() {
106-
let sum = calibrate_all(&read_equations(&get_input("prelim.txt")));
150+
let sum = calibrate_all(&read_equations(&get_input("prelim.txt")), false);
107151
assert_eq!(sum, 3749);
108152
}
109153

110154
#[test]
111155
fn test_part1() {
112-
let sum = calibrate_all(&read_equations(&get_input("input.txt")));
156+
let sum = calibrate_all(&read_equations(&get_input("input.txt")), false);
113157
assert_eq!(sum, 20281182715321);
114158
}
115159

160+
#[test]
161+
fn test_prelim2() {
162+
let sum = calibrate_all(&read_equations(&get_input("prelim.txt")), true);
163+
assert_eq!(sum, 11387);
164+
}
165+
166+
#[test]
167+
fn test_part2() {
168+
let sum = calibrate_all(&read_equations(&get_input("input.txt")), true);
169+
assert_eq!(sum, 159490400628354);
170+
}
171+
116172
fn main() {
117-
calibrate_all(&read_equations(&get_input("prelim.txt")));
118-
calibrate_all(&read_equations(&get_input("input.txt")));
173+
calibrate_all(&read_equations(&get_input("prelim.txt")), false);
174+
calibrate_all(&read_equations(&get_input("input.txt")), false);
175+
calibrate_all(&read_equations(&get_input("prelim.txt")), true);
176+
calibrate_all(&read_equations(&get_input("input.txt")), true);
119177
}

0 commit comments

Comments
 (0)