use crate::prelude::*; pub type I = Vec<(u64, Vec)>; pub type O = u64; fn _parse (data: &str) -> I { data.trim().lines().map(|e| e.trim().split_once(": ").map(|(left, right)| (p!(left), right.split_ascii_whitespace().map(|e| p!(e)).collect())).unwrap()).collect() } fn _solve (data: I, consider_concats: bool) -> O { data.iter().filter(|(val, list)| { let mut results: S = S::from([list[0]]); for &i in &list[1..] { for p in results.drain().collect_vec() { let prod = i * p; let sum = i + p; if prod <= *val { results.insert(prod); } if sum <= *val { results.insert(sum); } if consider_concats { let concat = p * 10u64.pow(i.ilog10() + 1) + i; if concat <= *val { results.insert(concat); } } } } results.contains(val) }).map(|(val, _)| val).sum() } fn _silver (data: I) -> O { _solve(data, false) } fn _gold (data: I) -> O { _solve(data, true) } #[cfg(test)] mod test { use super::*; fn read () -> I { let data = inc!(7); _parse(data) } #[test] fn silver () { let data = read(); let ans = _silver(data); assert_eq!(ans, 5837374519342) } #[test] fn gold () { let data = read(); let ans = _gold(data); assert_eq!(ans, 492383931650959) } }