Untitled
unknown
rust
a year ago
2.6 kB
43
Indexable
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)
}
Editor is loading...
Leave a Comment