diff --git a/src/days.rs b/src/days.rs index a44c1c7..fa88115 100644 --- a/src/days.rs +++ b/src/days.rs @@ -4,7 +4,7 @@ pub mod d3; pub mod d4; pub mod d5; pub mod d6; -// pub mod d7; +pub mod d7; // pub mod d8; // pub mod d9; // pub mod d10; diff --git a/src/days/d7.rs b/src/days/d7.rs new file mode 100644 index 0000000..05d1f08 --- /dev/null +++ b/src/days/d7.rs @@ -0,0 +1,62 @@ +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) + } +}