Advent of Code 2024 Day 7 - Rust
Given that parts one and two were so similar for this one, I am going to describe them both together. The solution for day seven was all in one function I called try_math
. For part one, can_concat was always false; that was an operation introduced in part two.
pub fn try_math(target: i64, current: i64, parts: &[i64], can_concat: bool) -> bool {
if parts.len() == 0 {
return false;
}
if current > target {
return false;
}
let next = parts[0];
if parts.len() == 1 {
let no_concat = current * next == target || current + next == target;
if can_concat {
let cc: i64 = (current.to_string() + &next.to_string()).parse().unwrap();
return (cc == target) || no_concat;
} else {
return no_concat;
}
} else {
let no_concat = try_math(target, current * next, &parts[1..], can_concat)
|| try_math(target, current + next, &parts[1..], can_concat);
if can_concat {
let cc: i64 = (current.to_string() + &next.to_string()).parse().unwrap();
return try_math(target, cc, &parts[1..], can_concat) || no_concat;
} else {
return no_concat;
}
}
}
This function takes a target value and a list of component parts and tries to combine the parts to meet the target using multiplication or addition (and concatenation in part two). The function is recursive with stop conditions if no parts are left to use or the current running total exceeds the target.
Numbers were always positive, so combining an extra element increased or maintained the current total, giving us the extra is current > target
stop condition.
If only a single part was left, we add or multiply current
by that value and test it against the target, returning a boolean. If more than one part is left, we recursively call the function with the first element removed and current
adjusted by either an addition, multiplication, or concatenation.
The complete solution can be found here.