From a037d203af8bc9482a793d8788a0d7c78fd04a39 Mon Sep 17 00:00:00 2001 From: Russell Champoux Date: Fri, 13 Dec 2024 16:17:02 +0000 Subject: [PATCH] day 13 pt 1 --- data/examples/13.txt | 15 ++++++++ src/bin/13.rs | 87 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 102 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 0000000..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 0000000..5151127 --- /dev/null +++ b/src/bin/13.rs @@ -0,0 +1,87 @@ +use itertools::Itertools; +use regex::Regex; + +advent_of_code::solution!(13); + +#[derive(Debug, Copy, Clone)] +struct Point { + x: T, + y: T +} + +#[derive(Debug, Copy, Clone)] +struct Machine { + a_button: Point, + b_button: Point, + prize: Point +} + +pub fn part_one(input: &str) -> Option { + let r_button = Regex::new(r"Button (A|B): X\+(\d+), Y\+(\d+)").unwrap(); + let r_prize = Regex::new(r"Prize: X=(\d+), Y=(\d+)").unwrap(); + + let machines = input.lines().chunks(4).into_iter().map(|chunk| { + let lines = chunk.collect_vec(); + assert!(lines.len() >= 3); + + let c_a = r_button.captures(lines[0]).unwrap(); + let a_button = Point { x: c_a[2].parse::().unwrap(), y: c_a[3].parse::().unwrap() }; + + let c_b = r_button.captures(lines[1]).unwrap(); + let b_button = Point { x: c_b[2].parse::().unwrap(), y: c_b[3].parse::().unwrap() }; + + let c_p = r_prize.captures(lines[2]).unwrap(); + let prize = Point { x: c_p[1].parse::().unwrap(), y: c_p[2].parse::().unwrap() }; + + Machine { a_button, b_button, prize } + }).collect_vec(); + + // println!("MACHINES {:?}", machines); + // BRUTE FORCE SOLUTION + let total_tokens: u32 = machines.iter().map(|machine| { + let matches = find_matches(*machine).collect_vec(); + let min = matches.iter().map(|(x, y)| 3 * x + y).min().unwrap_or(0); + // println!("MATCHES {:?}", matches); + min + }).sum(); + + Some(total_tokens) +} + +pub fn part_two(input: &str) -> Option { + None +} + +// TODO figure out how to reference-ify this +fn find_matches(machine: Machine) -> impl Iterator { + let result = (0..=100).flat_map(move |a_presses| { + (0..=100).filter_map(move |b_presses| { + let pos_x = machine.a_button.x * a_presses + machine.b_button.x * b_presses; + let pos_y = machine.a_button.y * a_presses + machine.b_button.y * b_presses; + if pos_x == machine.prize.x && pos_y == machine.prize.y { + // println!("FOUND POINT! ({}, {})", pos_x, pos_y); + Some((a_presses, b_presses)) + } else { + None + } + }) + }); + result +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_part_one() { + let result = part_one(&advent_of_code::template::read_file("examples", DAY)); + assert_eq!(result, Some(480)); + } + + #[test] + fn test_part_two() { + let result = part_two(&advent_of_code::template::read_file("examples", DAY)); + assert_eq!(result, None); + } +}