day 5 part 1
This commit is contained in:
77
5/main.ml
Normal file
77
5/main.ml
Normal 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
|
Reference in New Issue
Block a user