Advent of Code 2020
https://adventofcode.com/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('') and can be up to 35 characters long.
78 lines
2.4 KiB
78 lines
2.4 KiB
(* Common util. Should probably put this in a module or something.. *)


let get_one_line file =


try Some (input_line file) with


End_of_file > None




let get_lines file =


let rec input lines =


match get_one_line file with


Some line > input (line :: lines)


 None > List.rev lines


in input []




let read_file file =


let channel = open_in(file) in


get_lines channel




let (<<) f g x = f(g(x))


let (>>) f g x = g(f(x))




let rec take n (x :: xs) = (* take the first n elements *)


match n with


 0 > []


 n > x :: (take (n1) xs)




let rec drop n l = (* drop the first n elemnts *)


match n with


 0 > l


 n > drop (n1) @@ List.tl l




let sub_list start length = (* sub list from start *)


take length >> drop start




let list_sum = List.fold_left (+) 0




let list_max l = List.fold_left (fun acc x > if x > acc then x else acc) (List.hd l) l


let list_min l = List.fold_left (fun acc x > if x < acc then x else acc) (List.hd l) l




let range start len = (* makes a new list from start with length len *)


List.init len (fun x > x + 0) > List.map (fun x > x + start)




let flip f x y = f y x




(*  *)




let has_adders l target = (* do any 2 elements of l add up to target *)


match List.find_opt (fun x >


match List.find_opt (fun y > x != y && x + y = target) l with


 Some _ > true


 None > false


) l with


 Some _ > true


 None > false




let rec first_without_adders pre lines =


let x :: xs = lines in (* match out the head and tail *)


let cur = List.nth lines pre in (* grab the first row after the preamble *)


let sub = take pre lines in (* grab the preamble sublist *)


if has_adders sub cur (* chechk for adders *)


then first_without_adders pre xs (* if it has adders, recurse with the tail of the original list *)


else cur (* no adders! return this one *)




let rec all_sub_lists = function (* all combinations of sublists *)


 [] > []


 xs >


range 0 (List.length xs)


> List.map (fun len' > sub_list 0 len' xs)


> flip List.append (all_sub_lists @@ List.tl xs)




let () =


let lines = read_file "day9.txt" > List.map int_of_string in




let first = lines > first_without_adders 25 in


Printf.printf "first without 2 adders %i\n" first;




let all_subs = all_sub_lists lines in


let our_range = List.find (fun l > list_sum l = first) all_subs in


let our_sum = (list_max our_range) + (list_min our_range) in


Printf.printf "sum %i\n" our_sum;
