use super::Solution; pub struct Day03 {} impl Solution for Day03 { fn part1( &self, input: &mut Vec, ) -> Result, Box> { let battery_banks: Vec> = self.collect_banks(input); let batteries = 2; let mut total: u64 = 0; for bank in battery_banks { total += self.calculate_joltage(batteries, &bank); } Ok(Box::new(total)) } fn part2( &self, input: &mut Vec, ) -> Result, Box> { let battery_banks: Vec> = self.collect_banks(input); let batteries = 12; let mut total: u64 = 0; for bank in battery_banks { total += self.calculate_joltage(batteries, &bank); } Ok(Box::new(total)) } fn get_day(&self) -> u8 { 3 } } impl Day03 { /// Collect battery banks from input /// /// # Arguments /// * `arr` - Vec of strings representing battery banks /// /// # Returns /// * `Vec>` - Vector of battery banks as vectors of u8s fn collect_banks(&self, arr: &Vec) -> Vec> { let mut battery_banks: Vec> = vec![]; // Maps Battery banks into vec of u8s for bank in arr { let n = bank .as_str() .chars() .filter_map(|c| c.to_digit(10)) .map(|d| d as u8) .collect(); battery_banks.push(n); } battery_banks } /// Scan a slice of u8s to find the max int, /// (including its location) within the slice fn get_max(&self, arr: &[u8]) -> (u8, usize) { let mut max: u8 = 0; let mut max_idx: usize = 0; for (idx, i) in arr.iter().enumerate() { if *i > max { max = *i; max_idx = idx; } } (max, max_idx) } /// Calculate the joltage given a number of batteries and a bank /// /// # Arguments /// * `num_batteries` - Number of batteries to consider /// * `bank` - Slice of u8s representing the battery bank /// /// # Returns /// * `u64` - The calculated joltage fn calculate_joltage(&self, num_batteries: u8, bank: &[u8]) -> u64 { // Find the highest val in the avilable bank slice // leaving enough room for the remaining batteries let (max_val, max_idx) = self.get_max(&bank[0..=(bank.len() - (num_batteries as usize))]); // Base case: only one battery left to place if num_batteries == 1 { return max_val as u64; } // Otherwise, place the battery and recurse (max_val as u64) * 10u64.pow((num_batteries - 1) as u32) + self.calculate_joltage(num_batteries - 1, &bank[max_idx + 1..bank.len()]) } } /// Test from puzzle input #[cfg(test)] mod test { use super::*; use crate::*; #[test] fn part1() { let challenge = day03::Day03 {}; //Complete the Challenge let answer = challenge .part1( utils::get_input(challenge.get_day(), utils::InputType::Test1) .unwrap() .as_mut(), ) .unwrap() .to_string(); assert_eq!(answer, "357"); } #[test] fn part2() { let challenge = day03::Day03 {}; //Complete the Challenge let answer = challenge .part2( utils::get_input(challenge.get_day(), utils::InputType::Test2) .unwrap() .as_mut(), ) .unwrap() .to_string(); assert_eq!(answer, "3121910778619"); } }