Files
adventofcode2024/day_07/src/equation.rs

82 lines
2.2 KiB
Rust
Raw Normal View History

2025-06-16 11:32:05 -05:00
mod operator_set;
2025-06-16 12:58:38 -05:00
use std::collections::HashSet;
2025-06-16 12:59:46 -05:00
use operator_set::{Op, create_permutations};
2025-06-16 12:58:38 -05:00
2025-06-16 11:32:05 -05:00
#[derive(Debug)]
pub struct Equation {
answer: i64,
components: Vec<i64>,
}
impl Equation {
/// Create a new Equation from a string like:
///
/// Answer: components
/// 190: 10 19
pub fn new(equation_str: &str) -> Result<Equation, String> {
// Split answer and components
let split_equation: Vec<_> = equation_str.split(":").collect();
if split_equation.len() != 2 {
return Err(format!("Invalid equation string: {}", equation_str));
}
let answer = match split_equation[0].parse() {
Ok(a) => a,
Err(_) => {
return Err(format!(
"Error parsing answer {} in equation: {}",
split_equation[0], equation_str
));
}
};
// Parse components
let components = split_equation[1]
.split_whitespace()
.map(|c| match c.parse::<i64>() {
Ok(a) => Ok(a),
Err(_) => Err(format!(
"Error parsing component {} in equation: {}",
c, equation_str
)),
})
.collect::<Result<Vec<i64>, String>>()?;
Ok(Equation { answer, components })
}
pub fn answer(&self) -> i64 {
self.answer
}
pub fn components(&self) -> &Vec<i64> {
&self.components
}
2025-06-16 12:24:18 -05:00
fn compute_answer(&self, operators: &[Op]) -> i64 {
2025-06-16 11:32:05 -05:00
let mut accumulator = self.components[0];
2025-06-16 12:24:18 -05:00
for (i, op) in operators.iter().enumerate() {
match op {
Op::Multiply => accumulator *= self.components[i + 1],
Op::Add => accumulator += self.components[i + 1],
2025-06-16 11:32:05 -05:00
}
}
accumulator
}
2025-06-16 12:58:38 -05:00
pub fn solvable_multiply_add(&self) -> bool {
let op_combinations = create_permutations(
HashSet::from([Op::Add, Op::Multiply]),
self.components.len() - 1,
);
2025-06-16 11:32:05 -05:00
for combination in op_combinations {
if self.answer == self.compute_answer(&combination) {
return true;
}
}
false
}
}