Files
aoc2024/src/days/d3.rs
T
2024-12-03 22:58:22 +03:00

103 lines
2.4 KiB
Rust

#![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::<u64>() && let Ok(right) = right.parse::<u64>() {
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::<u64>() && let Ok(right) = right.parse::<u64>() {
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)
}
}