diff --git a/AdventOfCode2024/bin/main.ml b/AdventOfCode2024/bin/main.ml index b73f87a..bd1253b 100644 --- a/AdventOfCode2024/bin/main.ml +++ b/AdventOfCode2024/bin/main.ml @@ -13,7 +13,7 @@ let read_lines name = let () = print_endline "\nAdvent of Code 2024"; let part1, part2 = - read_lines "./inputs/06.txt" |> AdventOfCode2024.Day_06.solve + read_lines "./inputs/07.txt" |> AdventOfCode2024.Day_07.solve in Printf.printf "Part 1: %s\nPart 2: %s\n" (string_of_int part1) (string_of_int part2) diff --git a/AdventOfCode2024/lib/day_07.ml b/AdventOfCode2024/lib/day_07.ml new file mode 100644 index 0000000..4b75a06 --- /dev/null +++ b/AdventOfCode2024/lib/day_07.ml @@ -0,0 +1,67 @@ +type equation = { equals : int; numbers : int list } + +let rec print_list l = + match l with + | [] -> print_endline "" + | head :: tail -> + print_int head; + print_string ","; + print_list tail + +let equation_from_line line = + let first_num = Scanf.sscanf line "%d:" (fun n1 -> n1) in + let rest_of_numbers = + List.nth (String.split_on_char ':' line) 1 + |> String.trim |> String.split_on_char ' ' + in + let numbers = List.map int_of_string rest_of_numbers in + { equals = first_num; numbers } + +let attempt_solve { equals; numbers } = + (* [1, 2] *) + let rec loop numbers = + match numbers with + | head :: [] -> [ head ] + | head :: tail -> + let plus = List.map (fun i -> i + head) (loop tail) in + let times = List.map (fun i -> i * head) (loop tail) in + plus @ times + | _ -> raise (Invalid_argument "") + in + let possibilities = loop (List.rev numbers) in + if List.exists (fun i -> i == equals) possibilities then equals else 0 + +let attempt_solve_part2 { equals; numbers } = + (* [1, 2] *) + let rec loop numbers = + match numbers with + | head :: [] -> [ head ] + | head :: tail -> + let plus = List.map (fun i -> i + head) (loop tail) in + let times = List.map (fun i -> i * head) (loop tail) in + let concat = + List.map + (fun i -> + let i_string = string_of_int i in + let head_string = string_of_int head in + int_of_string (i_string ^ head_string)) + (loop tail) + in + plus @ times @ concat + | _ -> raise (Invalid_argument "") + in + let possibilities = loop (List.rev numbers) in + if List.exists (fun i -> i == equals) possibilities then equals else 0 + +let solve lines = + let part1 = + List.fold_left + (fun acc line -> acc + (equation_from_line line |> attempt_solve)) + 0 lines + in + let part2 = + List.fold_left + (fun acc line -> acc + (equation_from_line line |> attempt_solve_part2)) + 0 lines + in + (part1, part2)