open Printf;; let rec list_of_lines in_file = try let line = input_line in_file in line :: list_of_lines(in_file) with End_of_file -> close_in in_file; [] let get_input_lists list_of_lines = match list_of_lines with | towels_list :: _ :: tail -> (towels_list, tail) | _ -> raise (Invalid_argument "Not enough lines") let rec try_construct cache towels pattern = match Hashtbl.find_opt cache pattern with | Some result -> result | None -> let result = towels |> List.filter (fun towel -> String.starts_with ~prefix:towel pattern) |> List.map (fun towel -> try_construct cache towels (String.sub pattern (String.length towel) (String.length pattern - String.length towel))) |> List.fold_left Int.add 0 in Hashtbl.add cache pattern result; result let () = let f = open_in "input.txt" in let towels_str, patterns_list = list_of_lines f |> get_input_lists in let towels_list = towels_str |> String.split_on_char ',' |> List.map (fun x -> x |> String.trim) in let cache = Hashtbl.create 1024 in Hashtbl.add cache "" 1; let possibilities_list = patterns_list |> List.map (try_construct cache towels_list) in let result = possibilities_list |> List.filter (fun x-> x > 0) |> List.length in let result2 = List.fold_left Int.add 0 possibilities_list in printf "%d\n%d\n" result result2