Solve 13.1
This commit is contained in:
parent
1f49f71068
commit
67610d0808
1 changed files with 105 additions and 0 deletions
105
src/bin/13.rs
Normal file
105
src/bin/13.rs
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
use aoc::*;
|
||||||
|
use cached::proc_macro::cached;
|
||||||
|
use glam::U64Vec2;
|
||||||
|
use itertools::Itertools;
|
||||||
|
use regex::Regex;
|
||||||
|
|
||||||
|
const INPUT: &str = include_str!("../../input/13");
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
assert_example!(part1, "13-test", 480);
|
||||||
|
println!("Part 1: {}", part1(INPUT));
|
||||||
|
println!("Part 2: {}", part2(INPUT));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part1(input: &str) -> usize {
|
||||||
|
parse(input)
|
||||||
|
.into_iter()
|
||||||
|
.map(ClawMachine::tokens_to_win)
|
||||||
|
.sum()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part2(input: &str) -> usize {
|
||||||
|
parse(input)
|
||||||
|
.into_iter()
|
||||||
|
.map(ClawMachine::fix_conversion_error)
|
||||||
|
.map(ClawMachine::tokens_to_win2)
|
||||||
|
.sum()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse(input: &str) -> Vec<ClawMachine> {
|
||||||
|
input.split("\n\n").map(ClawMachine::parse).collect_vec()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)]
|
||||||
|
struct ClawMachine {
|
||||||
|
a: U64Vec2,
|
||||||
|
b: U64Vec2,
|
||||||
|
prize: U64Vec2,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ClawMachine {
|
||||||
|
fn fix_conversion_error(self) -> Self {
|
||||||
|
Self {
|
||||||
|
prize: U64Vec2::new(self.prize.x + 10000000000000, self.prize.y + 10000000000000),
|
||||||
|
..self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tokens_to_win(self) -> usize {
|
||||||
|
tokens_to_win(self, 0, 0, U64Vec2::ZERO)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tokens_to_win2(self) -> usize {
|
||||||
|
tokens_to_win2(self, 0, 0, U64Vec2::ZERO)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse(input: &str) -> Self {
|
||||||
|
let re =
|
||||||
|
Regex::new(r"X\+(\d+), Y\+(\d+)\n.*X\+(\d+), Y\+(\d+)\n.*X=(\d+), Y=(\d+)").unwrap();
|
||||||
|
let captures = re.captures(input).unwrap();
|
||||||
|
Self {
|
||||||
|
a: U64Vec2::new(captures[1].parse().unwrap(), captures[2].parse().unwrap()),
|
||||||
|
b: U64Vec2::new(captures[3].parse().unwrap(), captures[4].parse().unwrap()),
|
||||||
|
prize: U64Vec2::new(captures[5].parse().unwrap(), captures[6].parse().unwrap()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cached]
|
||||||
|
fn tokens_to_win(machine: ClawMachine, pressed_a: usize, pressed_b: usize, pos: U64Vec2) -> usize {
|
||||||
|
if pressed_a > 100 || pressed_b > 100 {
|
||||||
|
0
|
||||||
|
} else if pos == machine.prize {
|
||||||
|
pressed_a * 3 + pressed_b
|
||||||
|
} else if pos.x > machine.prize.x || pos.y > machine.prize.y {
|
||||||
|
0
|
||||||
|
} else {
|
||||||
|
let a = tokens_to_win(machine, pressed_a + 1, pressed_b, pos + machine.a);
|
||||||
|
let b = tokens_to_win(machine, pressed_a, pressed_b + 1, pos + machine.b);
|
||||||
|
match (a, b) {
|
||||||
|
(0, 0) => 0,
|
||||||
|
(a, 0) => a,
|
||||||
|
(0, b) => b,
|
||||||
|
(a, b) => a.min(b),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cached]
|
||||||
|
fn tokens_to_win2(machine: ClawMachine, pressed_a: usize, pressed_b: usize, pos: U64Vec2) -> usize {
|
||||||
|
if pos == machine.prize {
|
||||||
|
pressed_a * 3 + pressed_b
|
||||||
|
} else if pos.x > machine.prize.x || pos.y > machine.prize.y {
|
||||||
|
0
|
||||||
|
} else {
|
||||||
|
let a = tokens_to_win(machine, pressed_a + 1, pressed_b, pos + machine.a);
|
||||||
|
let b = tokens_to_win(machine, pressed_a, pressed_b + 1, pos + machine.b);
|
||||||
|
match (a, b) {
|
||||||
|
(0, 0) => 0,
|
||||||
|
(a, 0) => a,
|
||||||
|
(0, b) => b,
|
||||||
|
(a, b) => a.min(b),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue