diff --git a/2022/day8/src/main.rs b/2022/day8/src/main.rs index ff5a064..eb8a34a 100644 --- a/2022/day8/src/main.rs +++ b/2022/day8/src/main.rs @@ -82,7 +82,6 @@ fn main() -> std::io::Result<()> { } else { 0 }; - // println!("Right: {}, {:?}", right_score, right_part); let left_part = board[y].iter().rev().skip(x_inv).collect::>(); let left_score = if left_part.len() > 1 { let score = left_part @@ -99,7 +98,6 @@ fn main() -> std::io::Result<()> { } else { 0 }; - // println!("Left: {}, {:?}", left_score, left_part); let down_part = board.iter().map(|row| row[x]).skip(y).collect::>(); let down_score = if down_part.len() > 1 { let score = down_part @@ -116,7 +114,6 @@ fn main() -> std::io::Result<()> { } else { 0 }; - // println!("Down: {}, {:?}", down_score, down_part); let up_part = board .iter() .map(|row| row[x]) @@ -138,12 +135,7 @@ fn main() -> std::io::Result<()> { } else { 0 }; - // println!("Up: {}. {:?}", up_score, up_part); let tree_score = right_score * left_score * down_score * up_score; - // println!( - // "({}, {})({}) = {} = {} * {} * {} * {}", - // x, y, tree_from_top_left, tree_score, up_score, left_score, down_score, right_score - // ); scores[y][x] = tree_score; } } diff --git a/2024/Cargo.lock b/2024/Cargo.lock index 3d648ab..bd914cc 100644 --- a/2024/Cargo.lock +++ b/2024/Cargo.lock @@ -156,6 +156,7 @@ dependencies = [ "itertools", "log", "nom", + "regex", "test-log", "thiserror", ] diff --git a/2024/Cargo.toml b/2024/Cargo.toml index 0bb189b..adef030 100644 --- a/2024/Cargo.toml +++ b/2024/Cargo.toml @@ -26,7 +26,7 @@ rustworkx-core = "0.15.1" pathfinding = "4.11.0" test-log = {version="0.2.16", features=["default", "unstable"]} thiserror = "2.0.3" - +regex = "1.11.1" [profile.dhat] inherits = "release" diff --git a/2024/day-3/Cargo.toml b/2024/day-3/Cargo.toml index ba7dd09..31aca5a 100644 --- a/2024/day-3/Cargo.toml +++ b/2024/day-3/Cargo.toml @@ -15,6 +15,7 @@ log.workspace = true error-stack.workspace = true thiserror.workspace = true dhat.workspace = true +regex.workspace = true [dev-dependencies] test-log.workspace = true diff --git a/2024/day-3/src/part1.rs b/2024/day-3/src/part1.rs index 249d41e..8284521 100644 --- a/2024/day-3/src/part1.rs +++ b/2024/day-3/src/part1.rs @@ -2,6 +2,7 @@ use error_stack::Result; use thiserror::Error; +use regex::Regex; // day-3 #[derive(Debug, Error)] @@ -10,21 +11,22 @@ pub enum Day3Part1Error{ ParseError, } -pub fn part1 (_input: &str) -> Result { - Ok("Not Finished".to_string()) +pub fn part1 (input: &str) -> Result { + let re = Regex::new(r"mul\((\d{1,3}),(\d{1,3})\)").unwrap(); + Ok(re.captures_iter(input).map(|x| &x[1].parse::().unwrap() * &x[2].parse::().unwrap()).sum::().to_string()) } #[cfg(test)] mod test { use super::*; - const INPUT: &str = ""; + const INPUT: &str = "xmul(2,4)%&mul[3,7]!@^do_not_mul(5,5)+mul(32,64]then(mul(11,8)mul(8,5))"; #[test_log::test] #[test_log(default_log_filter = "trace")] fn part1_works() { let result = part1(INPUT).unwrap(); - assert_eq!(result, "Not Finished".to_string()); + assert_eq!(result, "161".to_string()); } } diff --git a/2024/day-3/src/part2.rs b/2024/day-3/src/part2.rs index 2d286cb..ba9233c 100644 --- a/2024/day-3/src/part2.rs +++ b/2024/day-3/src/part2.rs @@ -1,6 +1,7 @@ #![warn(clippy::all, clippy::pedantic)] use error_stack::Result; +use regex::Regex; use thiserror::Error; // day-3 @@ -10,21 +11,68 @@ pub enum Day3Part2Error{ ParseError, } -pub fn part2 (_input: &str) -> Result { - Ok("Not Finished".to_string()) +pub fn part2 (input: &str) -> Result { + let do_re = Regex::new(r"do\(\)").unwrap(); + let dos = do_re.find_iter(input).map(|x| (x.start(),x.end())).collect::>(); + let dont_re = Regex::new(r"don't\(\)").unwrap(); + let donts = dont_re.find_iter(input).map(|x| (x.start(),x.end())).collect::>(); + + let mut dos_index = 0; + let mut donts_index = 0; + let mut white_list = true; + let mut blackout_ranges = Vec::new(); + let mut blacklist_start = 0; + while dos_index < dos.len() && donts_index < donts.len(){ + if white_list { + if dos[dos_index].1 < donts[donts_index].0 { + //currently whitelisted so dos are no-ops + dos_index +=1; + } else { + blacklist_start = donts[donts_index].0; + white_list = false; + } + } else { + if donts[donts_index].1 < dos[dos_index].0 { + //in a black list so donts are no-ops + donts_index +=1; + } else { + blackout_ranges.push(blacklist_start..dos[dos_index].1); + blacklist_start = 0; + white_list = true; + } + } + } + if donts_index < donts.len() { + blackout_ranges.push(donts[donts_index].0..input.len()); + + } else if dos_index < dos.len() { + if blacklist_start != 0 { + blackout_ranges.push(blacklist_start..dos[dos_index].1); + } + } + let re = Regex::new(r"mul\((\d{1,3}),(\d{1,3})\)").unwrap(); + let mut sum = 0; + for mult_match in re.find_iter(input){ + if blackout_ranges.iter().any(|x| x.contains(&mult_match.start())) { + continue; + } + let values = re.captures(mult_match.as_str()).unwrap(); + sum += &values[1].parse::().unwrap() * &values[2].parse::().unwrap(); + } + Ok(sum.to_string()) } #[cfg(test)] mod test { use super::*; - const INPUT: &str = ""; + const INPUT: &str = "xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))"; #[test_log::test] #[test_log(default_log_filter = "trace")] fn part2_works() { let result = part2(INPUT).unwrap(); - assert_eq!(result, "Not Finished".to_string()); + assert_eq!(result, "48".to_string()); } }