diff options
Diffstat (limited to '2024_rust/src/bin')
-rw-r--r-- | 2024_rust/src/bin/day13.rs | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/2024_rust/src/bin/day13.rs b/2024_rust/src/bin/day13.rs new file mode 100644 index 0000000..92d7039 --- /dev/null +++ b/2024_rust/src/bin/day13.rs @@ -0,0 +1,129 @@ +use regex::Regex; + +#[derive(Debug)] +struct Machine1 { + a: (u32, u32), + b: (u32, u32), + prize: (u32, u32), +} + +impl Machine1 { + fn parse(input: &str) -> Vec<Self> { + let mut result: Vec<_> = vec![]; + let re = Regex::new( + r"Button A: X\+([0-9]+), Y\+([0-9]+) +Button B: X\+([0-9]+), Y\+([0-9]+) +Prize: X=([0-9]+), Y=([0-9]+)", + ) + .unwrap(); + for (_, [ax, ay, bx, by, x, y]) in re.captures_iter(input).map(|c| c.extract()) { + result.push(Machine1 { + a: (ax.parse().unwrap(), ay.parse().unwrap()), + b: (bx.parse().unwrap(), by.parse().unwrap()), + prize: (x.parse().unwrap(), y.parse().unwrap()), + }); + } + // println!("Result: {result:?}"); + result + } + + fn solve(&self) -> Option<(u32, u32)> { + for pushesb in (0..100).rev() { + for pushesa in 0..100 { + if self.prize.0 == self.a.0 * pushesa + self.b.0 * pushesb + && self.prize.1 == self.a.1 * pushesa + self.b.1 * pushesb + { + // println!("{self:?} solved with {pushesa} {pushesb} pushes!"); + return Some((pushesa, pushesb)); + } + } + } + None + } +} + +fn p1(input: &str) -> String { + let result: u32 = Machine1::parse(input) + .iter() + .filter_map(Machine1::solve) + .map(|(nx, ny)| nx * 3 + ny) + .sum(); + + result.to_string() +} + +#[derive(Debug)] +struct Machine2 { + a: (i64, i64), + b: (i64, i64), + prize: (i64, i64), +} + +fn intdiv(x: i64, y: i64) -> Option<i64> { + if x % y == 0 { + Some(x / y) + } else { + None + } +} + +impl Machine2 { + fn parse(input: &str) -> Vec<Self> { + let mut result: Vec<_> = vec![]; + let re = Regex::new( + r"Button A: X\+([0-9]+), Y\+([0-9]+) +Button B: X\+([0-9]+), Y\+([0-9]+) +Prize: X=([0-9]+), Y=([0-9]+)", + ) + .unwrap(); + for (_, [ax, ay, bx, by, x, y]) in re.captures_iter(input).map(|c| c.extract()) { + result.push(Machine2 { + a: (ax.parse().unwrap(), ay.parse().unwrap()), + b: (bx.parse().unwrap(), by.parse().unwrap()), + prize: ( + x.parse::<i64>().unwrap() + 10000000000000, + y.parse::<i64>().unwrap() + 10000000000000, + ), + }); + } + result + } + + fn solve(&self) -> Option<(i64, i64)> { + let pa = intdiv( + self.prize.0 * self.b.1 - self.prize.1 * self.b.0, + self.a.0 * self.b.1 - self.a.1 * self.b.0, + )?; + let pb = intdiv(self.prize.0 - (pa * self.a.0), self.b.0)?; + Some((pa, pb)) + } +} + +fn p2(input: &str) -> String { + let result: i64 = Machine2::parse(input) + .iter() + .filter_map(Machine2::solve) + .map(|(nx, ny)| nx * 3 + ny) + .sum(); + + result.to_string() +} + +fn main() { + aoc2024::run_day("13", p1, p2); +} + +#[cfg(test)] +mod tests { + use super::{p1, p2}; + + #[test] + fn day13_p1() { + assert_eq!(p1(&aoc2024::read_input("13")), "39290"); + } + + #[test] + fn day13_p2() { + assert_eq!(p2(&aoc2024::read_input("13")), "73458657399094"); + } +} |