Skip to content

Commit 944efe9

Browse files
committed
improve code for day13
1 parent 03367fc commit 944efe9

File tree

1 file changed

+50
-54
lines changed

1 file changed

+50
-54
lines changed

2024/day13/src/main.rs

Lines changed: 50 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ use regex::Regex;
22

33
#[derive(Debug)]
44
struct Machine {
5-
pub a: (usize, usize),
6-
pub b: (usize, usize),
7-
pub prize: (usize, usize),
5+
pub a: (i64, i64),
6+
pub b: (i64, i64),
7+
pub prize: (i64, i64),
88
}
99

1010
impl Machine {
@@ -27,28 +27,14 @@ Prize: X=(\d+), Y=(\d+)",
2727
}
2828
}
2929

30-
fn solve_integer(ax: isize, ay: isize, bx: isize, by: isize, tx: isize, ty: isize) -> usize {
31-
// calculate b using the derived formula:
32-
// given the system:
33-
// a*ax + b*ay = tx
34-
// a*bx + b*by = ty
35-
// after elimination, we get:
36-
// b = (ty*ax - tx*ay) / (by*ax - bx*ay)
37-
let b = (ty * ax - tx * ay) / (by * ax - bx * ay);
38-
39-
// using b, solve for a:
40-
// from a*ax + b*bx = tx -> a = (tx - b*bx) / ax
41-
let a = (tx - b * bx) / ax;
42-
43-
// verify
44-
if (ax * a + bx * b, ay * a + by * b) != (tx, ty) {
45-
return 0;
46-
}
47-
a as usize * 3 + b as usize
48-
}
49-
50-
// not working 🤷
51-
fn _solve_with_good_lp(ax: f64, ay: f64, bx: f64, by: f64, tx: f64, ty: f64) -> Option<u64> {
30+
// working for part1, but not for big number like part2 🤷 float imprecision ?
31+
fn _solve_with_good_lp(
32+
Machine {
33+
a: (ax, ay),
34+
b: (bx, by),
35+
prize: (tx, ty),
36+
}: Machine,
37+
) -> Option<u64> {
5238
use good_lp::*;
5339
variables! {
5440
vars:
@@ -58,8 +44,8 @@ fn _solve_with_good_lp(ax: f64, ay: f64, bx: f64, by: f64, tx: f64, ty: f64) ->
5844
let model = vars
5945
.minimise(a + b)
6046
.using(default_solver)
61-
.with(constraint!(a * ax + b * bx == tx))
62-
.with(constraint!(a * ay + b * by == ty));
47+
.with(constraint!(a * ax as f64 + b * bx as f64 == tx as f64))
48+
.with(constraint!(a * ay as f64 + b * by as f64 == ty as f64));
6349

6450
let solution = match model.solve() {
6551
Ok(sol) => sol,
@@ -72,36 +58,46 @@ fn _solve_with_good_lp(ax: f64, ay: f64, bx: f64, by: f64, tx: f64, ty: f64) ->
7258
Some(a_val.round() as u64 * 3 + b_val.round() as u64)
7359
}
7460

75-
fn part1(input: &str) -> usize {
76-
let machines = Machine::from_list(input);
77-
let mut used = 0;
78-
for Machine { a, b, prize } in machines {
79-
used += solve_integer(
80-
a.0 as isize,
81-
a.1 as isize,
82-
b.0 as isize,
83-
b.1 as isize,
84-
prize.0 as isize,
85-
prize.1 as isize,
86-
);
61+
// fn solve_integer(ax: isize, ay: isize, bx: isize, by: isize, tx: isize, ty: isize) -> usize {
62+
fn calculate(
63+
Machine {
64+
a: (ax, ay),
65+
b: (bx, by),
66+
prize: (tx, ty),
67+
}: Machine,
68+
) -> usize {
69+
// calculate b using the derived formula:
70+
// given the system:
71+
// a*ax + b*bx = tx
72+
// a*ay + b*by = ty
73+
// after elimination, we get:
74+
// b = (ty*ax - tx*ay) / (by*ax - bx*ay)
75+
let b = (ty * ax - tx * ay) / (by * ax - bx * ay);
76+
77+
// using b, solve for a:
78+
// from a*ax + b*bx = tx -> a = (tx - b*bx) / ax
79+
let a = (tx - b * bx) / ax;
80+
81+
// verify
82+
if (ax * a + bx * b, ay * a + by * b) != (tx, ty) {
83+
return 0;
8784
}
88-
used
85+
a as usize * 3 + b as usize
86+
}
87+
88+
fn part1(input: &str) -> usize {
89+
Machine::from_list(input).into_iter().map(calculate).sum()
8990
}
9091

9192
fn part2(input: &str) -> usize {
92-
let machines = Machine::from_list(input);
93-
let mut used = 0;
94-
for Machine { a, b, prize } in machines {
95-
used += solve_integer(
96-
a.0 as isize,
97-
a.1 as isize,
98-
b.0 as isize,
99-
b.1 as isize,
100-
prize.0 as isize + 10000000000000,
101-
prize.1 as isize + 10000000000000,
102-
);
103-
}
104-
used
93+
Machine::from_list(input)
94+
.into_iter()
95+
.map(|mut m| {
96+
m.prize.0 += 10000000000000;
97+
m.prize.1 += 10000000000000;
98+
calculate(m)
99+
})
100+
.sum()
105101
}
106102

107103
fn main() {
@@ -133,6 +129,6 @@ Prize: X=18641, Y=10279";
133129
}
134130
#[test]
135131
fn part2() {
136-
assert_eq!(super::part2(INPUT), 100);
132+
assert_eq!(super::part2(INPUT), 875318608908);
137133
}
138134
}

0 commit comments

Comments
 (0)