From 787610c66b0208ac0d21138bb639f052c9f9aeef Mon Sep 17 00:00:00 2001 From: Dustin Swan Date: Wed, 16 Dec 2020 15:43:45 -0500 Subject: [PATCH] day15 --- day15.ml | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ day15.txt | 3 ++ 2 files changed, 88 insertions(+) create mode 100644 day15.ml create mode 100644 day15.txt diff --git a/day15.ml b/day15.ml new file mode 100644 index 0000000..a4a0838 --- /dev/null +++ b/day15.ml @@ -0,0 +1,85 @@ +(* 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 explode s = (* convert a string to a list of chars *) + let rec exp i l = + if i < 0 then l else exp (i - 1) (s.[i] :: l) in + exp (String.length s - 1) [];; + +let implode l = String.of_seq (List.to_seq l) + +let (<<) f g x = f(g(x)) +let (>>) f g x = g(f(x)) +let flip f x y = f y x + +(* --- *) + +let rec find_idx x = function (* find index of x *) + | [] -> raise (Failure "Not Found") + | h :: t -> if x = h then 0 else 1 + find_idx x t + +let rec last = function + | [] -> raise (Failure "Empty List") + | x :: [] -> x + | x :: xs -> last xs + +let hash = Hashtbl.create 1000 + +let rec go idx last num = + (* Printf.printf "\nidx: %i. last num: %i\n" idx num; *) + + if idx = last - 1 + then num + else + let next = + try + let idx' = Hashtbl.find hash num in + let new_num = idx - idx' in + new_num + with Not_found _ -> 0 + in + let _ = Hashtbl.replace hash num idx in + go (idx+1) last next + +let () = + let nums = read_file "day15.txt" + |> flip List.nth 0 (* grab the first line *) + |> String.split_on_char ',' + |> List.map int_of_string + in + + List.iter (Printf.printf "%i ") nums; + print_newline (); + + (* pluck out the last number to start things off *) + let rev = List.rev nums in + let x :: xs = rev in + let nums' = List.rev xs in + + let starting_idx = List.length xs in + + (* Add the initial list to our hash *) + List.iteri (fun i x -> Hashtbl.add hash x i;) nums'; + + let final = go starting_idx 2020 x in + Printf.printf "after 2020: %i\n" final; + + Hashtbl.clear hash; + + List.iteri (fun i x -> Hashtbl.add hash x i;) nums'; + + let final' = go starting_idx 30000000 x in + Printf.printf "after 30000000: %i\n" final'; diff --git a/day15.txt b/day15.txt new file mode 100644 index 0000000..28af522 --- /dev/null +++ b/day15.txt @@ -0,0 +1,3 @@ +2,0,6,12,1,3 +3,2,1 +0,3,6