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 clean_string str = str |> String.split_on_char ':' |> List.hd let rec parse_int_list sep str = let list1 = (List.filter (fun a -> String.length a != 0) (String.split_on_char sep str)) in List.map (fun x -> int_of_string @@ clean_string x) list1 let rec is_possible_inner goal operand_list = match operand_list with | e1 :: tail1 -> begin match tail1 with | e2 :: tail2 -> is_possible_inner goal (e1 + e2 :: tail2) || is_possible_inner goal (e1 * e2 :: tail2) | _ -> goal == e1 end | _ -> false let is_possible input_lst = match input_lst with | head :: tail -> is_possible_inner head tail | _ -> false let rec int_concat a b = int_of_string (String.cat (string_of_int a) (string_of_int b)) let rec is_possible_extended_inner goal operand_list = match operand_list with | e1 :: tail1 -> begin match tail1 with | e2 :: tail2 -> is_possible_extended_inner goal (e1 + e2 :: tail2) || is_possible_extended_inner goal (e1 * e2 :: tail2) || is_possible_extended_inner goal (int_concat e1 e2 :: tail2) | _ -> goal == e1 end | _ -> false let is_possible_extended input_lst = match input_lst with | head :: tail -> is_possible_extended_inner head tail | _ -> false let () = let f = open_in "input.txt" in let lines = List.map (fun a -> parse_int_list ' ' a) (list_of_lines f) in let valid_lines = List.filter is_possible lines in let valid_lines2 = List.filter is_possible_extended lines in let result = List.fold_left (fun acc lst -> acc + List.hd lst) 0 valid_lines in let result2 = List.fold_left (fun acc lst -> acc + List.hd lst) 0 valid_lines2 in printf "%d\n%d\n" result result2