Untitled
pub fn solution(test: bool) -> ((usize, Duration), (usize, Duration)) { let lines; if test { lines = include_str!("../../../AdventOfCodeInputs/problem_inputs_2024/day_13_test.txt"); } else { lines = include_str!("../../../AdventOfCodeInputs/problem_inputs_2024/day_13.txt"); } (solve(&lines, false), solve(&lines, true)) } fn solve(lines: &str, p2: bool) -> (usize, Duration) { let now = Instant::now(); let claw_machines = lines .split("\n\n") .map(|x| ClawMachine::from_str(x)) .collect_vec(); let mut tokens = 0; for (i, machine) in claw_machines.iter().enumerate() { let mut machine = *machine; if p2 { machine.target = machine.target + OFFSET; } if let Some(ans) = machine.solve() { tokens += 3 * ans[(0, 0)].round() as isize + ans[(1, 0)].round() as isize; } } let ans = 0; (tokens as usize, now.elapsed()) } #[derive(Debug, Clone, Copy)] struct ClawMachine { buttons: Matrix2<f64>, target: Matrix2x1<f64>, } impl ClawMachine { fn from_str(lines: &str) -> Self { let mut lines = lines.lines(); let buttom_a_str = lines.next().unwrap().split(':').nth(1).unwrap(); let buttom_b_str = lines.next().unwrap().split(':').nth(1).unwrap(); let target_str = lines.next().unwrap().split(':').nth(1).unwrap(); let button_a = parse_button(buttom_a_str); let button_b = parse_button(buttom_b_str); let target = parse_button(target_str); let target = Matrix2x1::new(target.0 as f64, target.1 as f64); let buttons = Matrix2::new( button_a.0 as f64, button_a.1 as f64, button_b.0 as f64, button_b.1 as f64, ) .transpose(); ClawMachine { buttons, target } } fn solve(&self) -> Option<Matrix2x1<f64>> { let inv = self.buttons.try_inverse().unwrap(); let ans = inv * self.target; if check_fraction(ans[(0, 0)]) && check_fraction(ans[(1, 0)]) { Some(ans) } else { None } } } fn parse_button(line: &str) -> (isize, isize) { line.split(',') .map(|x| { x.trim() .chars() .skip(2) .collect::<String>() .parse() .unwrap() }) .collect_tuple() .unwrap() } fn check_fraction(num: f64) -> bool { (num as isize as f64 - num).abs() < ACC || (num as isize as f64 - num).abs() > (1.0 - ACC) }
Leave a Comment