Skip to content

Commit 09a2f6c

Browse files
committed
13th day
1 parent 2830333 commit 09a2f6c

File tree

2 files changed

+127
-0
lines changed

2 files changed

+127
-0
lines changed

data/examples/13.txt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
Button A: X+94, Y+34
2+
Button B: X+22, Y+67
3+
Prize: X=8400, Y=5400
4+
5+
Button A: X+26, Y+66
6+
Button B: X+67, Y+21
7+
Prize: X=12748, Y=12176
8+
9+
Button A: X+17, Y+86
10+
Button B: X+84, Y+37
11+
Prize: X=7870, Y=6450
12+
13+
Button A: X+69, Y+23
14+
Button B: X+27, Y+71
15+
Prize: X=18641, Y=10279

src/bin/13.rs

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
advent_of_code::solution!(13);
2+
3+
use advent_of_code::maneatingape::parse::*;
4+
5+
struct Point {
6+
x: i64,
7+
y: i64,
8+
}
9+
10+
impl Point {
11+
fn new(x: i64, y: i64) -> Self {
12+
Self { x, y }
13+
}
14+
}
15+
16+
struct Machine {
17+
a: Point,
18+
b: Point,
19+
prize: Point,
20+
}
21+
22+
fn parse_data(input: &str) -> Vec<Machine> {
23+
input
24+
.split("\n\n")
25+
.map(|x| {
26+
let mut x_iter = x.iter_signed();
27+
28+
Machine {
29+
a: Point::new(x_iter.next().unwrap(), x_iter.next().unwrap()),
30+
b: Point::new(x_iter.next().unwrap(), x_iter.next().unwrap()),
31+
prize: Point::new(x_iter.next().unwrap(), x_iter.next().unwrap()),
32+
}
33+
})
34+
.collect()
35+
}
36+
37+
fn calculate_press(machine: Machine) -> Option<(u64, u64)> {
38+
if let Some(b) = calculate_press_b(&machine) {
39+
if let Some(a) = calculate_press_a(&machine, b) {
40+
return Some((a, b));
41+
}
42+
}
43+
44+
None
45+
}
46+
47+
fn calculate_press_b(machine: &Machine) -> Option<u64> {
48+
let top = machine.prize.y * machine.a.x - machine.prize.x * machine.a.y;
49+
let bottom = machine.b.y * machine.a.x - machine.a.y * machine.b.x;
50+
51+
if top % bottom == 0 {
52+
Some((top / bottom) as u64)
53+
} else {
54+
None
55+
}
56+
}
57+
58+
fn calculate_press_a(machine: &Machine, press_b: u64) -> Option<u64> {
59+
let top = machine.prize.y - machine.b.y * press_b as i64;
60+
let bottom = machine.a.y;
61+
62+
if top % bottom == 0 {
63+
Some((top / bottom) as u64)
64+
} else {
65+
None
66+
}
67+
}
68+
69+
pub fn part_one(input: &str) -> Option<u64> {
70+
let data = parse_data(input);
71+
72+
let result = data
73+
.into_iter()
74+
.filter_map(calculate_press)
75+
.filter(|&(a, b)| a <= 100 && b <= 100)
76+
.fold(0, |acc, (a, b)| acc + a * 3 + b);
77+
78+
Some(result)
79+
}
80+
81+
pub fn part_two(input: &str) -> Option<u64> {
82+
let data = parse_data(input);
83+
84+
let result = data
85+
.into_iter()
86+
.map(|mut machine| {
87+
machine.prize.x += 10000000000000;
88+
machine.prize.y += 10000000000000;
89+
machine
90+
})
91+
.filter_map(calculate_press)
92+
.fold(0, |acc, (a, b)| acc + a * 3 + b);
93+
94+
Some(result)
95+
}
96+
97+
#[cfg(test)]
98+
mod tests {
99+
use super::*;
100+
101+
#[test]
102+
fn test_part_one() {
103+
let result = part_one(&advent_of_code::template::read_file("examples", DAY));
104+
assert_eq!(result, Some(480));
105+
}
106+
107+
#[test]
108+
fn test_part_two() {
109+
let result = part_two(&advent_of_code::template::read_file("examples", DAY));
110+
assert_eq!(result, Some(875318608908));
111+
}
112+
}

0 commit comments

Comments
 (0)