mod operator_set; use operator_set::{Op, create_operator_set}; #[derive(Debug)] pub struct Equation { answer: i64, components: Vec, } impl Equation { /// Create a new Equation from a string like: /// /// Answer: components /// 190: 10 19 pub fn new(equation_str: &str) -> Result { // 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::() { Ok(a) => Ok(a), Err(_) => Err(format!( "Error parsing component {} in equation: {}", c, equation_str )), }) .collect::, String>>()?; Ok(Equation { answer, components }) } pub fn answer(&self) -> i64 { self.answer } pub fn components(&self) -> &Vec { &self.components } fn compute_answer(&self, operators: &[Op]) -> i64 { let mut accumulator = self.components[0]; for (i, op) in operators.iter().enumerate() { match op { Op::Multiply => accumulator *= self.components[i + 1], Op::Add => accumulator += self.components[i + 1], } } accumulator } pub fn solvable(&self) -> bool { let op_combinations = create_operator_set(self.components.len() - 1); for combination in op_combinations { if self.answer == self.compute_answer(&combination) { return true; } } false } }