aoc/year2024/day13.rs
1//! # Claw Contraption
2//!
3//! Each claw machine is a system of two linear equations:
4//!
5//! ```none
6//! (Button A X) * (A presses) + (Button B X) * (B presses) = Prize X
7//! (Button A Y) * (A presses) + (Button B Y) * (B presses) = Prize Y
8//! ```
9//!
10//! Shortening the names and representing as a matrix:
11//!
12//! ```none
13//! [ ax bx ][ a ] = [ px ]
14//! [ ay by ][ b ] = [ py ]
15//! ```
16//!
17//! To solve we invert the 2 x 2 matrix then premultiply the right column.
18use crate::util::iter::*;
19use crate::util::parse::*;
20
21type Claw = [i64; 6];
22
23pub fn parse(input: &str) -> Vec<Claw> {
24 input.iter_signed().chunk::<6>().collect()
25}
26
27pub fn part1(input: &[Claw]) -> i64 {
28 input.iter().map(|row| play(row, 0)).sum()
29}
30
31pub fn part2(input: &[Claw]) -> i64 {
32 input.iter().map(|row| play(row, 10_000_000_000_000)).sum()
33}
34
35/// Invert the 2 x 2 matrix representing the system of linear equations.
36fn play(&[ax, ay, bx, by, px, py]: &Claw, offset: i64) -> i64 {
37 let (px, py) = (px + offset, py + offset);
38
39 // If determinant is zero there's no solution.
40 let det = ax * by - ay * bx;
41 if det == 0 {
42 return 0;
43 }
44
45 let a = by * px - bx * py;
46 let b = ax * py - ay * px;
47
48 // Integer solutions only.
49 if a % det != 0 || b % det != 0 {
50 return 0;
51 }
52
53 (3 * a + b) / det
54}