day15
parent
fab8323597
commit
787610c66b
@ -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';
|
Loading…
Reference in New Issue