2024 day 13 part 1

This commit is contained in:
2024-12-13 09:16:31 +00:00
parent 932b2c926c
commit 8d7c14a707
2 changed files with 73 additions and 2 deletions

69
bin/day2413.ml Normal file
View File

@@ -0,0 +1,69 @@
let parse_machine line_a line_b prize_pos =
let re_ab = Str.regexp {|Button [AB]: X\+\([0-9]+\), Y\+\([0-9]+\)|} in
let re_pos = Str.regexp {|Prize: X=\([0-9]+\), Y=\([0-9]+\)|} in
let _ = Str.search_forward re_ab line_a 0 in
let a =
( int_of_string (Str.matched_group 1 line_a),
int_of_string (Str.matched_group 2 line_a) )
in
let _ = Str.search_forward re_ab line_b 0 in
let b =
( int_of_string (Str.matched_group 1 line_b),
int_of_string (Str.matched_group 2 line_b) )
in
let _ = Str.search_forward re_pos prize_pos 0 in
let prize =
( int_of_string (Str.matched_group 1 prize_pos),
int_of_string (Str.matched_group 2 prize_pos) )
in
(a, b, prize)
let parse_machines =
let rec impl acc = function
| "" :: t -> impl acc t
| a :: b :: p :: t -> impl (parse_machine a b p :: acc) t
| [] -> acc
| _ -> failwith "parse_machines.impl"
in
impl []
let machines_of_file fname = Aoc.strings_of_file fname |> parse_machines
(*
We want to solve A * a.x + B * b.x = X
and A * a.y + B * b.y = Y
which is
A * a.x / b.x + B = X / b.x
A * a.y / b.y + B = Y / b.y
A * (a.x / b.x - a.y / b.y) = X / b.x - Y / b.y
A * (a.x * b.y - a.y * b.x) / b.x / b.y = X / b.x - Y / b.y
A * (a.x * b.y - a.y * b.x) = X * b.y - Y * b.x
A = (X * b.y - Y * b.x) / (a.x * by.y - a.y * b.x)
(7870 * 37 - 6450 * 84) / (17 * 37 - 86 * 84)
80 - (8400 * 67 - 5400 * 22) / (94 * 67 - 34 * 22)
a = (94, 34) b = (22, 67) p = (8400, 5400)
[ a.x b.x ] [ A ] = [ X ]
[ a.y b.y ] [ B ] [ Y ]
*)
let calc_tokens ((ax, ay), (bx, by), (x, y)) =
let a_n = (x * by) - (y * bx) in
let a_d = (ax * by) - (ay * bx) in
Printf.printf
"a = (%d, %d) b = (%d, %d) p = (%d, %d), a_n / a_d = %d / %d, mod = %d\n"
ax ay bx by x y a_n a_d (a_n mod a_d);
if a_n mod a_d <> 0 then None
else if a_n / a_d <= 0 then None
else
let a = a_n / a_d in
let b = (x - (ax * a)) / bx in
Printf.printf " a = %d b = %d\n" a b;
Some ((3 * a) + b)
let part machines =
List.map calc_tokens machines
|> List.filter_map Fun.id |> List.fold_left ( + ) 0
let _ = Aoc.main machines_of_file [ (string_of_int, part) ]

View File

@@ -11,7 +11,8 @@
day2409 day2409
day2410 day2410
day2411 day2411
day2412) day2412
day2413)
(names (names
day2401 day2401
day2402 day2402
@@ -24,5 +25,6 @@
day2409 day2409
day2410 day2410
day2411 day2411
day2412) day2412
day2413)
(libraries str aoc)) (libraries str aoc))