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
|
|
|
|
|
}
|
|
|
|
|
}
|