#![allow(unused_imports)] use crate::prelude::*; pub type I = &'static str; pub type O = u64; fn _silver (data: I) -> O { let mut sum = 0; let mut data = data; while let Some(f) = data.find("mul(") { data = &data[f..]; let start = 4; let Some(fin) = data.find(')') else { break }; let inside = &data[start..fin]; if let Some((left, right)) = inside.split_once(',') { if let Ok(left) = left.parse::() && let Ok(right) = right.parse::() { sum += left * right; } else { data = &data[start..]; continue; } } else { data = &data[start..]; continue; } data = &data[fin+1..]; } sum } fn _gold (data: I) -> O { let mut sum = 0; let mut enabled = true; let mut data = data; loop { let mul = data.find("mul(").unwrap_or(usize::MAX); let _do = data.find("do()").unwrap_or(usize::MAX); let dont = data.find("don't()").unwrap_or(usize::MAX); if [mul, _do, dont].iter().all(|&e| e == usize::MAX) { break; } let next = mul.min(_do).min(dont); if next == mul { data = &data[next..]; let start = 4; let Some(fin) = data.find(')') else { break }; let inside = &data[start..fin]; if let Some((left, right)) = inside.split_once(',') { if let Ok(left) = left.parse::() && let Ok(right) = right.parse::() { if enabled { sum += left * right; } } else { data = &data[start..]; continue; } } else { data = &data[start..]; continue; } data = &data[fin+1..]; } else if next == _do { enabled = true; data = &data[next+4..]; } else if next == dont { enabled = false; data = &data[next+7..]; } } sum } #[cfg(test)] mod test { use super::*; fn read () -> &'static str { inc!(3) } #[test] fn silver () { let data = read(); let ans = _silver(data); assert_eq!(ans, 181345830) } #[test] fn gold () { let data = read(); let ans = _gold(data); assert_eq!(ans, 98729041) } }