From 000001705070bd731eb7b5a4250d8a368a6cefca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Jane=C5=BEi=C4=8D?= Date: Fri, 13 Dec 2024 09:34:43 +0100 Subject: [PATCH] solution: day 13 --- data/examples/13.txt | 15 +++++++++ src/bin/13.rs | 79 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 data/examples/13.txt create mode 100644 src/bin/13.rs diff --git a/data/examples/13.txt b/data/examples/13.txt new file mode 100644 index 000000000..912f482 --- /dev/null +++ b/data/examples/13.txt @@ -0,0 +1,15 @@ +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 diff --git a/src/bin/13.rs b/src/bin/13.rs new file mode 100644 index 000000000..b235bf8 --- /dev/null +++ b/src/bin/13.rs @@ -0,0 +1,79 @@ +use regex::Regex; + +fn parse_input(input: &str) -> Vec<[(isize, isize); 3]> { + let r = Regex::new(r".*X(?:=|\+)(\d*), Y(?:=|\+)(\d*)").unwrap(); + + let mut parsed = Vec::new(); + + for machine in input.split("\n\n") { + let mut p = [(0, 0); 3]; + for (idx, line) in machine.lines().enumerate() { + let c = r.captures(line).unwrap(); + let x: isize = c.get(1).unwrap().as_str().parse().unwrap(); + let y: isize = c.get(2).unwrap().as_str().parse().unwrap(); + + p[idx] = (x, y); + } + parsed.push(p) + } + + parsed +} + +fn solve(m: ((isize, isize), (isize, isize)), v: (isize, isize)) -> Option { + let det = m.0 .0 * m.1 .1 - m.0 .1 * m.1 .0; + + if det == 0 { + return None; + } + + let x = (v.0 * m.1 .1 - m.0 .1 * v.1) as f64 / det as f64; + let y = (m.0 .0 * v.1 - v.0 * m.1 .0) as f64 / det as f64; + + if x.trunc() != x || y.trunc() != y { + return None; + } + + Some(x as isize * 3 + y as isize) +} + +pub fn part_one(input: &str) -> Option { + parse_input(input) + .into_iter() + .filter_map(|[(a1, b1), (a2, b2), t]| solve(((a1, a2), (b1, b2)), t)) + .sum::() + .into() +} + +pub fn part_two(input: &str) -> Option { + let prize_add = 10_000_000_000_000; + + parse_input(input) + .into_iter() + .filter_map(|[(a0, b0), (a1, b1), (t0, t1)]| { + solve(((a0, a1), (b0, b1)), (t0 + prize_add, t1 + prize_add)) + }) + .sum::() + .into() +} + +aoc::solution!(13); + +#[cfg(test)] +mod tests { + use super::*; + #[test] + fn test_part_one() { + assert_eq!( + part_one(&aoc::template::read_file("examples", 13)), + Some(480) + ); + } + #[test] + fn test_part_two() { + assert_eq!( + part_two(&aoc::template::read_file("examples", 13)), + Some(875318608908) + ); + } +}