From 8d7c14a70751fb1f2fda9259177368661401296c Mon Sep 17 00:00:00 2001 From: Matthew Gretton-Dann Date: Fri, 13 Dec 2024 09:16:31 +0000 Subject: [PATCH] 2024 day 13 part 1 --- bin/day2413.ml | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++ bin/dune | 6 +++-- 2 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 bin/day2413.ml diff --git a/bin/day2413.ml b/bin/day2413.ml new file mode 100644 index 0000000..370696a --- /dev/null +++ b/bin/day2413.ml @@ -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) ] diff --git a/bin/dune b/bin/dune index 506ca60..c984710 100644 --- a/bin/dune +++ b/bin/dune @@ -11,7 +11,8 @@ day2409 day2410 day2411 - day2412) + day2412 + day2413) (names day2401 day2402 @@ -24,5 +25,6 @@ day2409 day2410 day2411 - day2412) + day2412 + day2413) (libraries str aoc))