From 120fe4c9e696ec3289736843f54657fdf2b8247d Mon Sep 17 00:00:00 2001 From: Tom van der Lee Date: Tue, 3 Dec 2024 10:01:25 +0100 Subject: Day3 --- .idea/aoc2024.iml | 1 + Cargo.toml | 2 +- aoc/src/lib.rs | 34 +++++++++++++++++------- day3/Cargo.toml | 8 ++++++ day3/src/main.rs | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 114 insertions(+), 10 deletions(-) create mode 100644 day3/Cargo.toml create mode 100644 day3/src/main.rs diff --git a/.idea/aoc2024.iml b/.idea/aoc2024.iml index 784d79e..779b5d8 100644 --- a/.idea/aoc2024.iml +++ b/.idea/aoc2024.iml @@ -6,6 +6,7 @@ + diff --git a/Cargo.toml b/Cargo.toml index 766c71c..2e030b6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,3 +1,3 @@ [workspace] -members = ["aoc", "day1", "day2"] +members = ["aoc", "day1", "day2", "day3"] resolver = "2" diff --git a/aoc/src/lib.rs b/aoc/src/lib.rs index c4318e1..dcca651 100644 --- a/aoc/src/lib.rs +++ b/aoc/src/lib.rs @@ -2,6 +2,7 @@ use clap::Parser; use std::fs::File; use std::io; use std::io::{BufRead, BufReader, Read}; +use std::panic::catch_unwind; use std::time::Instant; #[derive(Parser, Debug)] @@ -16,6 +17,14 @@ struct Args { pub trait Day { fn example_input(&self) -> &'static str; + fn example_input_part_1(&self) -> &'static str { + self.example_input() + } + + fn example_input_part_2(&self) -> &'static str { + self.example_input() + } + fn example_result_part_1(&self) -> &'static str; fn example_result_part_2(&self) -> &'static str; @@ -61,19 +70,26 @@ pub fn main(day: &dyn Day) { println!("Time to run: {}s", now.elapsed().as_secs_f64()); } -pub fn test_day(day: &T) { +pub fn test_day(day: &T) { use std::io::Cursor; use std::io::{BufReader, Read}; - let example_input = day.example_input(); - // Test Part 1 - let input = BufReader::new(Box::new(Cursor::new(example_input)) as Box); - let output = day.part_1(input); - assert_eq!(output.trim(), day.example_result_part_1(), "Part 1 failed"); + let output = catch_unwind(|| { + let input = BufReader::new(Box::new(Cursor::new(day.example_input_part_1())) as Box); + day.part_1(input) + }); + if output.is_ok() { + assert_eq!(output.unwrap().trim(), day.example_result_part_1(), "Part 1 failed"); + } // Test Part 2 - let input = BufReader::new(Box::new(Cursor::new(example_input)) as Box); - let output = day.part_2(input); - assert_eq!(output.trim(), day.example_result_part_2(), "Part 2 failed"); + let output = catch_unwind(|| { + let input = BufReader::new(Box::new(Cursor::new(day.example_input_part_2())) as Box); + day.part_2(input) + }); + + if output.is_ok() { + assert_eq!(output.unwrap().trim(), day.example_result_part_2(), "Part 2 failed"); + } } \ No newline at end of file diff --git a/day3/Cargo.toml b/day3/Cargo.toml new file mode 100644 index 0000000..cabf6e3 --- /dev/null +++ b/day3/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "day3" +version = "0.1.0" +edition = "2021" + +[dependencies] +aoc = { path = "../aoc" } +regex = "1.11.1" \ No newline at end of file diff --git a/day3/src/main.rs b/day3/src/main.rs new file mode 100644 index 0000000..86ba39b --- /dev/null +++ b/day3/src/main.rs @@ -0,0 +1,79 @@ + +use aoc; +use std::io::{BufReader, Read}; +use aoc::Day; +use regex::Regex; + +struct Day3 {} + +impl Day for Day3 { + fn example_input(&self) -> &'static str { + r#" + xmul(2,4)%&mul[3,7]!@^do_not_mul(5,5)+mul(32,64]then(mul(11,8)mul(8,5)) + "#.trim() + } + + fn example_input_part_2(&self) -> &'static str { + r#" + xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5)) + "#.trim() + } + + fn example_result_part_1(&self) -> &'static str { + "161" + } + + fn example_result_part_2(&self) -> &'static str { + "48" + } + + fn part_1(&self, input: BufReader>) -> String { + let code = self.read_lines(input).iter().map(|l| l.trim()).collect::>().join(""); + let re = Regex::new(r"mul\((?P\d+),(?P\d+)\)").unwrap(); + re + .captures_iter(&code) + .map(|c| { + c.name("a").unwrap().as_str().parse::().unwrap() * c.name("b").unwrap().as_str().parse::().unwrap() + }) + .sum::() + .to_string() + } + + fn part_2(&self, input: BufReader>) -> String { + let code = self.read_lines(input).iter().map(|l| l.trim()).collect::>().join(""); + println!("{}", code); + + let mut mul = true; + let re = Regex::new(r"mul\((?P\d+),(?P\d+)\)|(?Pdo)\(\)|(?Pdon't)\(\)").unwrap(); + re + .captures_iter(&code) + .map(|c| { + + if c.name("enable") != None { + mul = true; + } else if c.name("disable") != None { + mul = false; + } else if mul { + return c.name("a").unwrap().as_str().parse::().unwrap() * c.name("b").unwrap().as_str().parse::().unwrap(); + } + + 0 + }) + .sum::() + .to_string() + } +} + + +fn main() { + aoc::main(&Day3 {}); +} + +#[cfg(test)] +mod tests { + use super::*; + #[test] + fn test_day3() { + aoc::test_day(&Day3 {}); + } +} -- cgit v1.2.3