solution: day 13

This commit is contained in:
Matej Janezic 2024-12-13 09:34:43 +01:00
parent 00000160fd
commit 0000017050
Signed by: janezicmatej
GPG Key ID: 4298E230ED37B2C0
2 changed files with 94 additions and 0 deletions

15
data/examples/13.txt Normal file
View File

@ -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

79
src/bin/13.rs Normal file
View File

@ -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<isize> {
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<isize> {
parse_input(input)
.into_iter()
.filter_map(|[(a1, b1), (a2, b2), t]| solve(((a1, a2), (b1, b2)), t))
.sum::<isize>()
.into()
}
pub fn part_two(input: &str) -> Option<isize> {
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::<isize>()
.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)
);
}
}