day 9
parent
0d1acd3f49
commit
0b6976dd86
@ -0,0 +1,78 @@
|
||||
(* 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 (n-1) xs)
|
||||
|
||||
let rec drop n l = (* drop the first n elemnts *)
|
||||
match n with
|
||||
| 0 -> l
|
||||
| n -> drop (n-1) @@ 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 sub-lists *)
|
||||
| [] -> []
|
||||
| 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;
|
Loading…
Reference in New Issue