From 0000005092296ded587d525c6165aa82ac2c5542 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Jane=C5=BEi=C4=8D?= Date: Tue, 3 Dec 2024 07:22:09 +0100 Subject: [PATCH] solution: day 3 --- data/examples/03.txt | 1 + src/bin/03.rs | 89 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 data/examples/03.txt create mode 100644 src/bin/03.rs diff --git a/data/examples/03.txt b/data/examples/03.txt new file mode 100644 index 000000000..30032cb --- /dev/null +++ b/data/examples/03.txt @@ -0,0 +1 @@ +xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5)) diff --git a/src/bin/03.rs b/src/bin/03.rs new file mode 100644 index 000000000..bc4dd78 --- /dev/null +++ b/src/bin/03.rs @@ -0,0 +1,89 @@ +use regex::Regex; + +fn get_mul_a_b_start(input: &str) -> Vec<(usize, usize, usize)> { + let r = Regex::new(r"mul\((\d+),(\d+)\)").unwrap(); + + r.captures_iter(input) + .map(|x| { + let a = x.get(1).unwrap().as_str().parse().unwrap(); + let b = x.get(2).unwrap().as_str().parse().unwrap(); + let start = x.get(0).unwrap().start(); + + (a, b, start) + }) + .collect() +} + +fn get_do_start(input: &str) -> Vec { + let d = Regex::new(r"do\(\)").unwrap(); + d.captures_iter(input) + .map(|x| x.get(0).unwrap().start()) + .collect() +} + +fn get_dont_start(input: &str) -> Vec { + let n = Regex::new(r"don't\(\)").unwrap(); + n.captures_iter(input) + .map(|x| x.get(0).unwrap().start()) + .collect() +} + +pub fn part_one(input: &str) -> Option { + get_mul_a_b_start(input) + .into_iter() + .map(|(a, b, _)| a * b) + .sum::() + .into() +} + +pub fn part_two(input: &str) -> Option { + let ds = get_do_start(input); + let ns = get_dont_start(input); + + let mut c = 0; + let mut d = None; + let mut n = None; + + // increment pointer p while ps[p] < s, ps needs to be sorted + let mv_ptr = |ps: &[usize], p: Option, s| { + ps.iter() + .enumerate() + .skip(p.unwrap_or_default()) + .take_while(|(_, &x)| x < s) + .last() + .map(|x| x.0) + }; + + for (a, b, s) in get_mul_a_b_start(input) { + d = mv_ptr(&ds, d, s); + n = mv_ptr(&ns, n, s); + if match (d, n) { + (None, Some(_)) => true, + (Some(dd), Some(nn)) if ds[dd] < ns[nn] => true, + _ => false, + } { + continue; + } + + c += a * b; + } + c.into() +} + +aoc::solution!(3); + +#[cfg(test)] +mod tests { + use super::*; + #[test] + fn test_part_one() { + assert_eq!( + part_one(&aoc::template::read_file("examples", 3)), + Some(161) + ); + } + #[test] + fn test_part_two() { + assert_eq!(part_two(&aoc::template::read_file("examples", 3)), Some(48)); + } +}