summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.idea/aoc2024.iml1
-rw-r--r--Cargo.toml2
-rw-r--r--aoc/src/lib.rs34
-rw-r--r--day3/Cargo.toml8
-rw-r--r--day3/src/main.rs79
5 files changed, 114 insertions, 10 deletions
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 @@
6 <sourceFolder url="file://$MODULE_DIR$/day1/src" isTestSource="false" /> 6 <sourceFolder url="file://$MODULE_DIR$/day1/src" isTestSource="false" />
7 <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" /> 7 <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
8 <sourceFolder url="file://$MODULE_DIR$/day2/src" isTestSource="false" /> 8 <sourceFolder url="file://$MODULE_DIR$/day2/src" isTestSource="false" />
9 <sourceFolder url="file://$MODULE_DIR$/day3/src" isTestSource="false" />
9 <excludeFolder url="file://$MODULE_DIR$/aoc/target" /> 10 <excludeFolder url="file://$MODULE_DIR$/aoc/target" />
10 <excludeFolder url="file://$MODULE_DIR$/target" /> 11 <excludeFolder url="file://$MODULE_DIR$/target" />
11 </content> 12 </content>
diff --git a/Cargo.toml b/Cargo.toml
index 766c71c..2e030b6 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,3 +1,3 @@
1[workspace] 1[workspace]
2members = ["aoc", "day1", "day2"] 2members = ["aoc", "day1", "day2", "day3"]
3resolver = "2" 3resolver = "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;
2use std::fs::File; 2use std::fs::File;
3use std::io; 3use std::io;
4use std::io::{BufRead, BufReader, Read}; 4use std::io::{BufRead, BufReader, Read};
5use std::panic::catch_unwind;
5use std::time::Instant; 6use std::time::Instant;
6 7
7#[derive(Parser, Debug)] 8#[derive(Parser, Debug)]
@@ -16,6 +17,14 @@ struct Args {
16 17
17pub trait Day { 18pub trait Day {
18 fn example_input(&self) -> &'static str; 19 fn example_input(&self) -> &'static str;
20 fn example_input_part_1(&self) -> &'static str {
21 self.example_input()
22 }
23
24 fn example_input_part_2(&self) -> &'static str {
25 self.example_input()
26 }
27
19 fn example_result_part_1(&self) -> &'static str; 28 fn example_result_part_1(&self) -> &'static str;
20 fn example_result_part_2(&self) -> &'static str; 29 fn example_result_part_2(&self) -> &'static str;
21 30
@@ -61,19 +70,26 @@ pub fn main(day: &dyn Day) {
61 println!("Time to run: {}s", now.elapsed().as_secs_f64()); 70 println!("Time to run: {}s", now.elapsed().as_secs_f64());
62} 71}
63 72
64pub fn test_day<T: Day>(day: &T) { 73pub fn test_day<T: Day + std::panic::RefUnwindSafe>(day: &T) {
65 use std::io::Cursor; 74 use std::io::Cursor;
66 use std::io::{BufReader, Read}; 75 use std::io::{BufReader, Read};
67 76
68 let example_input = day.example_input();
69
70 // Test Part 1 77 // Test Part 1
71 let input = BufReader::new(Box::new(Cursor::new(example_input)) as Box<dyn Read>); 78 let output = catch_unwind(|| {
72 let output = day.part_1(input); 79 let input = BufReader::new(Box::new(Cursor::new(day.example_input_part_1())) as Box<dyn Read>);
73 assert_eq!(output.trim(), day.example_result_part_1(), "Part 1 failed"); 80 day.part_1(input)
81 });
82 if output.is_ok() {
83 assert_eq!(output.unwrap().trim(), day.example_result_part_1(), "Part 1 failed");
84 }
74 85
75 // Test Part 2 86 // Test Part 2
76 let input = BufReader::new(Box::new(Cursor::new(example_input)) as Box<dyn Read>); 87 let output = catch_unwind(|| {
77 let output = day.part_2(input); 88 let input = BufReader::new(Box::new(Cursor::new(day.example_input_part_2())) as Box<dyn Read>);
78 assert_eq!(output.trim(), day.example_result_part_2(), "Part 2 failed"); 89 day.part_2(input)
90 });
91
92 if output.is_ok() {
93 assert_eq!(output.unwrap().trim(), day.example_result_part_2(), "Part 2 failed");
94 }
79} \ No newline at end of file 95} \ 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 @@
1[package]
2name = "day3"
3version = "0.1.0"
4edition = "2021"
5
6[dependencies]
7aoc = { path = "../aoc" }
8regex = "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 @@
1
2use aoc;
3use std::io::{BufReader, Read};
4use aoc::Day;
5use regex::Regex;
6
7struct Day3 {}
8
9impl Day for Day3 {
10 fn example_input(&self) -> &'static str {
11 r#"
12 xmul(2,4)%&mul[3,7]!@^do_not_mul(5,5)+mul(32,64]then(mul(11,8)mul(8,5))
13 "#.trim()
14 }
15
16 fn example_input_part_2(&self) -> &'static str {
17 r#"
18 xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))
19 "#.trim()
20 }
21
22 fn example_result_part_1(&self) -> &'static str {
23 "161"
24 }
25
26 fn example_result_part_2(&self) -> &'static str {
27 "48"
28 }
29
30 fn part_1(&self, input: BufReader<Box<dyn Read>>) -> String {
31 let code = self.read_lines(input).iter().map(|l| l.trim()).collect::<Vec<&str>>().join("");
32 let re = Regex::new(r"mul\((?P<a>\d+),(?P<b>\d+)\)").unwrap();
33 re
34 .captures_iter(&code)
35 .map(|c| {
36 c.name("a").unwrap().as_str().parse::<u32>().unwrap() * c.name("b").unwrap().as_str().parse::<u32>().unwrap()
37 })
38 .sum::<u32>()
39 .to_string()
40 }
41
42 fn part_2(&self, input: BufReader<Box<dyn Read>>) -> String {
43 let code = self.read_lines(input).iter().map(|l| l.trim()).collect::<Vec<&str>>().join("");
44 println!("{}", code);
45
46 let mut mul = true;
47 let re = Regex::new(r"mul\((?P<a>\d+),(?P<b>\d+)\)|(?P<enable>do)\(\)|(?P<disable>don't)\(\)").unwrap();
48 re
49 .captures_iter(&code)
50 .map(|c| {
51
52 if c.name("enable") != None {
53 mul = true;
54 } else if c.name("disable") != None {
55 mul = false;
56 } else if mul {
57 return c.name("a").unwrap().as_str().parse::<u32>().unwrap() * c.name("b").unwrap().as_str().parse::<u32>().unwrap();
58 }
59
60 0
61 })
62 .sum::<u32>()
63 .to_string()
64 }
65}
66
67
68fn main() {
69 aoc::main(&Day3 {});
70}
71
72#[cfg(test)]
73mod tests {
74 use super::*;
75 #[test]
76 fn test_day3() {
77 aoc::test_day(&Day3 {});
78 }
79}