module CS = Set.Make(Char) let set_of_string str = let rec aux s i st = if i < 0 then st else aux s (i - 1) (CS.add s.[i] st) in aux str ((String.length str) - 1) CS.empty let all_char_set = "abcdefghijklmnopqrstuvwxyz" |> set_of_string let read_lines name = let ic = open_in name in let try_read () = try Some (input_line ic) with End_of_file -> None in let rec loop acc group = match try_read () with | Some "" -> loop (group :: acc) [] | Some s -> loop acc (s :: group) | None -> close_in ic; (group :: acc) in loop [] [] let part1 filename = read_lines filename |> List.map (fun x -> x |> (String.concat "") |> set_of_string |> CS.cardinal) |> List.fold_left (+) 0 let part2 filename = read_lines filename |> List.map (fun x -> x |> List.map set_of_string |> List.fold_left CS.inter all_char_set |> CS.cardinal) |> List.fold_left (+) 0 let () = print_endline (string_of_int (part1 "day6.input")) let () = print_endline (string_of_int (part2 "day6.input"))