day 5 part 1

This commit is contained in:
2024-12-06 00:42:48 +01:00
parent 83f8326ccb
commit ce7a2efbd9

77
5/main.ml Normal file
View File

@@ -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