let input = Reuse.split "inputs/day01.txt" '\n' 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 ("Day 1 Part 1 test failed: expected 3, got " ^ string_of_int part1_result); if part2_result <> 8 then failwith ("Day 1 Part 2 test failed: expected 8, got " ^ string_of_int part2_result); Printf.printf "All Day 1 tests passed!\n" end let () = Tests.run_tests()