From: Greg Burri Date: Fri, 13 Dec 2024 21:40:10 +0000 (+0100) Subject: Day 13 X-Git-Url: https://git.euphorik.ch/?a=commitdiff_plain;h=0fcfeb68034271faf9959fd4f965b5bb4b85c067;p=advent_of_code_2024.git Day 13 --- diff --git a/src/day13.rs b/src/day13.rs new file mode 100644 index 0000000..7de4a3f --- /dev/null +++ b/src/day13.rs @@ -0,0 +1,95 @@ +use std::io::BufRead; + +use nalgebra::{stack, Vector2}; +use regex::Regex; + +type Equations = Vec<(Vector2, Vector2, Vector2)>; + +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::().unwrap(), + a_cap.get(2).unwrap().as_str().parse::().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::().unwrap(), + b_cap.get(2).unwrap().as_str().parse::().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::().unwrap(), + prize_cap.get(2).unwrap().as_str().parse::().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::(), b_v.cast::()].determinant(); + if d == 0f64 { + return None; + } + let a = (stack![xy.cast::(), b_v.cast::()].determinant() / d) as i64; + let b = (stack![a_v.cast::(), xy.cast::()].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); + } +} diff --git a/src/days.rs b/src/days.rs index 2851217..0ff4d85 100644 --- a/src/days.rs +++ b/src/days.rs @@ -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)) + ) +} diff --git a/src/main.rs b/src/main.rs index a081792..1b92c94 100644 --- a/src/main.rs +++ b/src/main.rs @@ -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,