(* * SPDX-FileCopyrightText: Copyright 2025 Alexandre Jesus * * SPDX-License-Identifier: GPL-3.0-or-later *) let parse_range s = match String.split_on_char '-' s with | [a; b] -> (int_of_string a, int_of_string b) | _ -> failwith ("Invalid range " ^ s) let parse_ranges ch = In_channel.input_all ch |> String.trim |> String.split_on_char ',' |> List.map parse_range let is_invalid s cnt = cnt > 0 && (String.length s) mod cnt = 0 && String.to_seqi s |> Seq.drop cnt |> Seq.for_all (fun (i, c) -> c = s.[i - cnt]) let is_invalid_part1 a = let s = string_of_int a in let l = String.length s in is_invalid s (l / 2) let sum_invalid_ids invalid_fn (a, b) = Seq.ints a |> Seq.take (b - a + 1) |> Seq.filter invalid_fn |> Seq.fold_left (+) 0 let solve ch invalid_fn = parse_ranges ch |> List.map (sum_invalid_ids invalid_fn) |> List.fold_left (+) 0 |> Printf.printf "%d\n" let part1 ch = solve ch is_invalid_part1 let is_invalid_part2 a = let s = string_of_int a in let l = String.length s in Seq.ints 1 |> Seq.take (l / 2) |> Seq.exists (is_invalid s) let part2 ch = solve ch is_invalid_part2