63 lines
1.4 KiB
Rust
63 lines
1.4 KiB
Rust
use crate::prelude::*;
|
|
|
|
pub type I = Vec<(u64, Vec<u64>)>;
|
|
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<u64> = 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)
|
|
}
|
|
}
|