static DAY: u8 = 11; fn main() { let input = advent::read_lines(DAY); println!("{DAY}a: {}", blink_stones(&input[0])); println!("{DAY}b: {}", 0); } enum Stone { Number(u64), Split(Box,Box), } impl Stone { fn blink_number(number: u64) -> Stone { /* rule 1 */ if number == 0 { return Stone::Number(1); } /* rule 2 */ let number_str = number.to_string(); if number_str.len() % 2 == 0 { let left = number_str.chars().take(number_str.len() / 2).collect::(); let right = number_str.chars().skip(number_str.len() / 2).collect::(); let left = left.parse::().unwrap(); let right = right.parse::().unwrap(); return Stone::Split(Box::new(Stone::Number(left)), Box::new(Stone::Number(right))); } /* rule 3 */ Stone::Number(2024 * number) } fn blink_stone(stone: &Stone) -> Stone { match stone { Stone::Number(number) => Self::blink_number(*number), Stone::Split(left, right) => Stone::Split(Box::new(Self::blink_stone(left)), Box::new(Self::blink_stone(right))), } } fn blink(&mut self) { *self = Self::blink_stone(self); } fn count(&self) -> usize { match self { Stone::Number(_) => 1, Stone::Split(left, right) => left.count() + right.count(), } } } fn blink_stones(input: &str) -> usize { let mut stones = Vec::new(); for val in input.split(" ") { let number = val.parse::().unwrap(); stones.push(Stone::Number(number)); } for _ in 0..25 { for stone in stones.iter_mut() { stone.blink(); } } stones.iter() .map(|stone| stone.count()) .sum() } #[cfg(test)] mod tests { use super::*; #[test] fn test() { let input = "125 17"; assert_eq!(blink_stones(input), 55312); } }