Day 13
authorGreg Burri <greg.burri@gmail.com>
Fri, 13 Dec 2024 21:40:10 +0000 (22:40 +0100)
committerGreg Burri <greg.burri@gmail.com>
Fri, 13 Dec 2024 21:40:10 +0000 (22:40 +0100)
src/day13.rs [new file with mode: 0644]
src/days.rs
src/main.rs

diff --git a/src/day13.rs b/src/day13.rs
new file mode 100644 (file)
index 0000000..7de4a3f
--- /dev/null
@@ -0,0 +1,95 @@
+use std::io::BufRead;
+
+use nalgebra::{stack, Vector2};
+use regex::Regex;
+
+type Equations = Vec<(Vector2<i64>, Vector2<i64>, Vector2<i64>)>;
+
+pub fn read(reader: &mut dyn BufRead) -> Equations {
+    let button_a = Regex::new(r#"Button A: X\+(\d+), Y\+(\d+)"#).unwrap();
+    let button_b = Regex::new(r#"Button B: X\+(\d+), Y\+(\d+)"#).unwrap();
+    let prize = Regex::new(r#"Prize: X=(\d+), Y=(\d+)"#).unwrap();
+
+    let mut equations = Vec::new();
+    let mut iter = reader.lines();
+    loop {
+        if let Some(Ok(line1)) = iter.next() {
+            let a_cap = button_a.captures(&line1).unwrap();
+            let a_factors = Vector2::new(
+                a_cap.get(1).unwrap().as_str().parse::<i64>().unwrap(),
+                a_cap.get(2).unwrap().as_str().parse::<i64>().unwrap(),
+            );
+            let line2 = iter.next().unwrap().unwrap();
+            let b_cap = button_b.captures(&line2).unwrap();
+            let b_factors = Vector2::new(
+                b_cap.get(1).unwrap().as_str().parse::<i64>().unwrap(),
+                b_cap.get(2).unwrap().as_str().parse::<i64>().unwrap(),
+            );
+            let line3 = iter.next().unwrap().unwrap();
+            let prize_cap = prize.captures(&line3).unwrap();
+            let prize_xy = Vector2::new(
+                prize_cap.get(1).unwrap().as_str().parse::<i64>().unwrap(),
+                prize_cap.get(2).unwrap().as_str().parse::<i64>().unwrap(),
+            );
+            let _ = iter.next();
+            equations.push((a_factors, b_factors, prize_xy));
+        } else {
+            break;
+        }
+    }
+    equations
+}
+
+pub fn add_10000000000000_to_xy(equations: Equations) -> Equations {
+    equations
+        .into_iter()
+        .map(|(a_v, b_v, xy)| (a_v, b_v, xy.add_scalar(10000000000000)))
+        .collect()
+}
+
+pub fn nb_tokens(equations: &Equations) -> i64 {
+    equations
+        .iter()
+        .filter_map(|(a_v, b_v, xy)| {
+            let d = stack![a_v.cast::<f64>(), b_v.cast::<f64>()].determinant();
+            if d == 0f64 {
+                return None;
+            }
+            let a = (stack![xy.cast::<f64>(), b_v.cast::<f64>()].determinant() / d) as i64;
+            let b = (stack![a_v.cast::<f64>(), xy.cast::<f64>()].determinant() / d) as i64;
+
+            if a * a_v[0] + b * b_v[0] == xy[0] && a * a_v[1] + b * b_v[1] == xy[1] {
+                Some(3 * a + b)
+            } else {
+                None
+            }
+        })
+        .sum()
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    static BUTTON_BEHAVIORS: &str = "Button A: X+94, Y+34
+Button B: X+22, Y+67
+Prize: X=8400, Y=5400
+
+Button A: X+26, Y+66
+Button B: X+67, Y+21
+Prize: X=12748, Y=12176
+
+Button A: X+17, Y+86
+Button B: X+84, Y+37
+Prize: X=7870, Y=6450
+
+Button A: X+69, Y+23
+Button B: X+27, Y+71
+Prize: X=18641, Y=10279";
+
+    #[test]
+    fn part1() {
+        let equations = read(&mut BUTTON_BEHAVIORS.as_bytes());
+        assert_eq!(nb_tokens(&equations), 480);
+    }
+}
index 2851217..0ff4d85 100644 (file)
@@ -114,3 +114,12 @@ pub fn day12(reader: &mut dyn BufRead) -> String {
         day12::total_price(&garden, true)
     )
 }
+
+pub fn day13(reader: &mut dyn BufRead) -> String {
+    let equations = day13::read(reader);
+    format!(
+        "part1: {}, part2: {}",
+        day13::nb_tokens(&equations),
+        day13::nb_tokens(&day13::add_10000000000000_to_xy(equations))
+    )
+}
index a081792..1b92c94 100644 (file)
@@ -14,7 +14,7 @@ mod day09;
 mod day10;
 mod day11;
 mod day12;
-// mod day13;
+mod day13;
 // mod day14;
 // mod day15;
 // mod day16;
@@ -45,7 +45,7 @@ fn main() {
         days::day10,
         days::day11,
         days::day12,
-        // days::day13,
+        days::day13,
         // days::day14,
         // days::day15,
         // days::day16,