From ce7a2efbd9f500c936a8a91b4d902363702d73c9 Mon Sep 17 00:00:00 2001 From: Acvaxoort Date: Fri, 6 Dec 2024 00:42:48 +0100 Subject: [PATCH] day 5 part 1 --- 5/main.ml | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 5/main.ml diff --git a/5/main.ml b/5/main.ml new file mode 100644 index 0000000..b69c8ce --- /dev/null +++ b/5/main.ml @@ -0,0 +1,77 @@ +open Printf;; +open String;; +open Map;; + +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 is_not_empty lst = + match lst with + | [] -> false + | _ -> true + +let rec parse_int_list sep str = + let list1 = (List.filter (fun a -> length a != 0) (String.split_on_char sep str)) in + List.map int_of_string list1 + +module IntMap = Map.Make(Int) +module IntSet = Set.Make(Int) + +let rec parse_ordering lines must_be_before = + match lines with + | head :: tail -> + if length head > 0 then + let elems = parse_int_list '|' head in + let e1 = List.hd elems in + let e2 = List.nth elems 1 in + let update_fun prev = + match prev with + | Some set -> Some (IntSet.add e1 set) + | None -> Some (IntSet.add e1 IntSet.empty) in + let new_map = IntMap.update e2 update_fun must_be_before in + parse_ordering tail new_map + else + (tail, must_be_before) + | _ -> (lines, must_be_before) + +let parse in_file = + let lines = list_of_lines in_file in + let lines_rest, must_be_before = parse_ordering lines IntMap.empty in + let entries = List.map (fun str -> List.rev @@ parse_int_list ',' str) lines_rest in + (must_be_before, entries) + +let rec is_good must_be_before already_appeared entry = + match entry with + | head :: tail -> begin + let new_already_appeared = IntSet.add head already_appeared in + match IntMap.find_opt head must_be_before with + | Some set -> + let intersect = IntSet.inter set new_already_appeared in + if IntSet.is_empty intersect then + is_good must_be_before new_already_appeared tail + else + false + | None -> + is_good must_be_before new_already_appeared tail + end + | _ -> true + +let rec summarise_good_entries must_be_before entries = + match entries with + | head :: tail -> + if is_good must_be_before IntSet.empty head then + List.nth head (List.length head / 2) + summarise_good_entries must_be_before tail + else + summarise_good_entries must_be_before tail + | _ -> 0 + +let () = + let f = open_in "input.txt" in + let must_be_before, entries = parse f in + let result = summarise_good_entries must_be_before entries in + printf "%d\n" result \ No newline at end of file