diff --git a/day_07/src/equation.rs b/day_07/src/equation.rs new file mode 100644 index 0000000..b9987c1 --- /dev/null +++ b/day_07/src/equation.rs @@ -0,0 +1,85 @@ +mod operator_set; + +use operator_set::create_operator_set; + +#[derive(Debug, Clone, Copy)] +enum Ops { + Multiply, + Add, +} + +#[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: &[bool]) -> i64 { + let mut accumulator = self.components[0]; + + for (i, op_bool) in operators.iter().enumerate() { + if *op_bool { + // Multiply + accumulator *= self.components[i + 1]; + } else { + // 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 + } +} diff --git a/day_07/src/equation/operator_set.rs b/day_07/src/equation/operator_set.rs new file mode 100644 index 0000000..d8b6815 --- /dev/null +++ b/day_07/src/equation/operator_set.rs @@ -0,0 +1,26 @@ +use std::collections::HashSet; + +fn create_operator_set_recurse( + operators_permutation_set: &mut HashSet>, + operators: Vec, +) { + operators_permutation_set.insert(operators.clone()); + if !operators.contains(&false) { + return; + } + + for i in 0..operators.len() { + if operators[i] { + continue; + } + let mut new_operators = operators.clone(); + new_operators[i] = true; + create_operator_set_recurse(operators_permutation_set, new_operators); + } +} + +pub fn create_operator_set(num_of_operators: usize) -> HashSet> { + let mut operator_sets: HashSet> = HashSet::new(); + create_operator_set_recurse(&mut operator_sets, vec![false; num_of_operators]); + operator_sets +} diff --git a/day_07/src/main.rs b/day_07/src/main.rs index a320e55..92a3fc3 100644 --- a/day_07/src/main.rs +++ b/day_07/src/main.rs @@ -2,112 +2,16 @@ // // Run command: cargo run ./input.txt +mod equation; + use std::{ - collections::HashSet, env, error::Error, fs::File, io::{BufReader, prelude::*}, }; -fn create_operator_set_recurse( - operators_permutation_set: &mut HashSet>, - operators: Vec, -) { - operators_permutation_set.insert(operators.clone()); - if !operators.contains(&false) { - return; - } - - for i in 0..operators.len() { - if operators[i] { - continue; - } - let mut new_operators = operators.clone(); - new_operators[i] = true; - create_operator_set_recurse(operators_permutation_set, new_operators); - } -} - -fn create_operator_set(num_of_operators: usize) -> HashSet> { - let mut operator_sets: HashSet> = HashSet::new(); - create_operator_set_recurse(&mut operator_sets, vec![false; num_of_operators]); - operator_sets -} - -#[derive(Debug, Clone, Copy)] -enum Ops { - Multiply, - Add, -} - -#[derive(Debug)] -struct Equation { - answer: i64, - components: Vec, -} - -impl Equation { - /// Create a new Equation from a string like: - /// - /// Answer: components - /// 190: 10 19 - 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 }) - } - - fn compute_answer(&self, operators: &[bool]) -> i64 { - let mut accumulator = self.components[0]; - - for (i, op_bool) in operators.iter().enumerate() { - if *op_bool { - // Multiply - accumulator *= self.components[i + 1]; - } else { - // Add - accumulator += self.components[i + 1]; - } - } - - accumulator - } - - 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 - } -} +use equation::Equation; fn main() -> Result<(), Box> { // Handle command input @@ -129,11 +33,6 @@ fn main() -> Result<(), Box> { equations.push(Equation::new(&line)?) } - println!("{:?}", equations); - - let operator_set = create_operator_set(3); - println!("{:?}", operator_set); - let mut value_sum = 0; println!("Is solvable?"); @@ -142,7 +41,7 @@ fn main() -> Result<(), Box> { let solvable = equation.solvable(); println!("{:?} => {}", equation, solvable); if solvable { - value_sum += equation.answer; + value_sum += equation.answer(); } }