aoc25_ocaml/lib/day1.ml
2025-12-02 22:54:16 +01:00

86 lines
2.3 KiB
OCaml

let input = Reuse.split_lines "inputs/day1.txt"
let convert (s : string): int =
let first_char = s.[0] in
let remainder = String.sub s 1 (String.length s - 1) in
let distance = int_of_string remainder in
match first_char with
| 'L' -> -distance
| 'R' -> distance
| _ -> raise (Invalid_argument "Invalid input")
let count_if_zero (counter: int) (position: int) =
if position == 0 then counter + 1 else counter
let normalize_position (pos : int) (modulus : int) =
let result = pos mod modulus in
if result >= 0 then result else result + modulus
let count_boundary_crossings (counter: int) (position: int) (movement: int) =
let full_rotations = abs movement / 100 in
let remaining_movement = movement mod 100 in
let new_position = position + remaining_movement in
let boundary_crossings =
if (new_position >= 100 && position < 100) ||
(new_position <= 0 && position > 0) then 1 else 0
in
counter + full_rotations + boundary_crossings
let rec update (values: int list) (position: int) (counter: int) : int =
match values with
| [] -> counter
| x :: xs -> let new_position = normalize_position (position + x) 100 in
update xs new_position (count_if_zero counter new_position)
let rec update_part2 (values: int list) (position: int) (counter: int) : int =
match values with
| [] -> counter
| x :: xs -> let new_position = normalize_position (position + x) 100 in
update_part2 xs new_position (count_boundary_crossings counter position x)
let solve_part1 (lines: string list) : int =
update (List.map convert lines) 50 0
let solve_part2 (lines: string list) : int =
update_part2 (List.map convert lines) 50 0
let day1_part1 : int =
solve_part1 input
let day1_part2 : int =
solve_part2 input
module Tests = struct
let test_input = "L268
L30
R48
L5
R60
L55
L1
L99
R14
L82"
let test_lines = String.split_on_char '\n' test_input
let run_tests () =
let part1_result = solve_part1 test_lines in
let part2_result = solve_part2 test_lines in
if part1_result <> 3 then
failwith ("Part 1 test failed: expected 3, got " ^ string_of_int part1_result);
if part2_result <> 8 then
failwith ("Part 2 test failed: expected 8, got " ^ string_of_int part2_result);
Printf.printf "All tests passed!\n"
end
let () = Tests.run_tests()