]> localhost Git - adventofcode2024.git/commitdiff
Complete day 3
authorJack Kinsey <j.jameskinsey@gmail.com>
Wed, 4 Dec 2024 04:51:48 +0000 (23:51 -0500)
committerJack Kinsey <j.jameskinsey@gmail.com>
Wed, 4 Dec 2024 04:51:48 +0000 (23:51 -0500)
Cargo.lock
Cargo.toml
src/day03.rs [new file with mode: 0644]
src/main.rs

index cc11b73b6856ea41544312d3ee3b6ea6af0bb273..8a07bf0ec7789a3942ee443eb154f1ebaed185db 100644 (file)
@@ -5,3 +5,50 @@ version = 3
 [[package]]
 name = "adventofcode2024"
 version = "0.1.0"
+dependencies = [
+ "regex",
+]
+
+[[package]]
+name = "aho-corasick"
+version = "1.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "memchr"
+version = "2.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
+
+[[package]]
+name = "regex"
+version = "1.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-automata",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-automata"
+version = "0.4.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
index 83a1806a8f4b8b6f7005ed45d3606fc35e1c270d..1339bf6e9ca649506423c13a0fc1b5cbe92693e5 100644 (file)
@@ -4,3 +4,4 @@ version = "0.1.0"
 edition = "2021"
 
 [dependencies]
+regex = "1.11.1"
diff --git a/src/day03.rs b/src/day03.rs
new file mode 100644 (file)
index 0000000..e0bf43c
--- /dev/null
@@ -0,0 +1,100 @@
+use regex::Regex;
+
+fn input() -> &'static str {
+    include_str!("../input/day03.txt")
+}
+
+#[derive(Debug, Eq, PartialEq, Copy, Clone)]
+enum Op {
+    Do,
+    DoNot,
+    Mul(u16, u16),
+}
+
+fn parse(input: &str) -> Vec<Op> {
+    Regex::new(
+        r"(?x)( # flag x ignores whitespace
+        (mul)\((\d\d?\d?),(\d\d?\d?)\)
+        | (do|don't)\(()()\) # we need throwaway groups to keep the number of groups the same
+        )",
+    )
+    .unwrap()
+    .captures_iter(input)
+    .map(|c| c.extract())
+    .map(|(_, [_, ins, a, b])| match ins {
+        "do" => Op::Do,
+        "don't" => Op::DoNot,
+        "mul" => Op::Mul(a.parse().unwrap(), b.parse().unwrap()),
+        _ => panic!(),
+    })
+    .collect()
+}
+
+fn eval(state: bool, op: &Op) -> (bool, u32) {
+    match (state, op) {
+        (_, Op::Do) => (true, 0),
+        (_, Op::DoNot) => (false, 0),
+        (true, Op::Mul(a, b)) => (state, u32::from(*a) * u32::from(*b)),
+        (false, Op::Mul(_, _)) => (state, 0),
+    }
+}
+
+fn exec(prog: &[Op]) -> u32 {
+    prog.iter()
+        .fold((true, 0u32), |(state, n), op| {
+            let (new, del) = eval(state, op);
+            (new, n + del)
+        })
+        .1
+}
+
+pub fn part1() {
+    let ops = parse(input());
+    let n: u32 = ops.iter().map(|o| eval(true, o).1).sum();
+    println!("Day 3 Part 1: {}", n);
+}
+
+pub fn part2() {
+    let ops = parse(input());
+    let n: u32 = exec(&ops);
+    println!("Day 3 Part 2: {}", n);
+}
+
+#[cfg(test)]
+mod test {
+    use super::*;
+
+    const INPUT_STR: &str =
+        concat!("xmul(2,4)%&mul[3,7]!@^do_not_mul(5,5)+mul(32,64]then(mul(11,8)mul(8,5))");
+
+    const INPUT_STR2: &str =
+        concat!("xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))");
+
+    #[test]
+    fn test_parse() {
+        assert_eq!(
+            parse(INPUT_STR),
+            vec![Op::Mul(2, 4), Op::Mul(5, 5), Op::Mul(11, 8), Op::Mul(8, 5),]
+        )
+    }
+
+    #[test]
+    fn test_parse2() {
+        assert_eq!(
+            parse(INPUT_STR2),
+            vec![
+                Op::Mul(2, 4),
+                Op::DoNot,
+                Op::Mul(5, 5),
+                Op::Mul(11, 8),
+                Op::Do,
+                Op::Mul(8, 5),
+            ]
+        )
+    }
+
+    #[test]
+    fn test_exec() {
+        assert_eq!(exec(&parse(INPUT_STR2)), 48);
+    }
+}
index 48fa201c004068c2d973eed5cd3922218fb0d57e..d6680b52d35824891362ebf694419c31f50b486e 100644 (file)
@@ -1,6 +1,6 @@
 pub mod day01;
 pub mod day02;
-// pub mod day03;
+pub mod day03;
 // pub mod day04;
 // pub mod day05;
 // pub mod day06;
@@ -26,10 +26,10 @@ pub mod day02;
 
 type Part = fn();
 
-const DAYS: [(Part, Part); 2] = [
+const DAYS: [(Part, Part); 3] = [
     (day01::part1 as fn(), day01::part2 as fn()),
     (day02::part1 as fn(), day02::part2 as fn()),
-    // (day03::part1 as fn(), day03::part2 as fn()),
+    (day03::part1 as fn(), day03::part2 as fn()),
     // (day04::part1 as fn(), day04::part2 as fn()),
     // (day05::part1 as fn(), day05::part2 as fn()),
     // (day06::part1 as fn(), day06::part2 as fn()),