From be7c370916b56e4df1e5e3c1ad2d2bba681e4ae0 Mon Sep 17 00:00:00 2001 From: Aryadev Chavali Date: Fri, 1 Nov 2024 01:39:53 +0000 Subject: Finish puzzle 3 of 2015 in ocaml --- 2015/puzzle-3.ml | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 2015/puzzle-3.ml diff --git a/2015/puzzle-3.ml b/2015/puzzle-3.ml new file mode 100644 index 0000000..ae7663e --- /dev/null +++ b/2015/puzzle-3.ml @@ -0,0 +1,71 @@ +let read_all filename = + let ic = open_in filename in + let read_char () = + try Some (input_char ic) + with End_of_file -> None in + let rec read_chars cur = + match read_char () with + | Some s -> read_chars (s :: cur) + | None -> + close_in ic; List.rev cur in + read_chars [] + +let table_inc table dir = + if Hashtbl.mem table dir then + let new_rec = (Hashtbl.find table dir) + 1 in + Hashtbl.replace table dir new_rec + else + Hashtbl.add table dir 1 + +let move_direction table dir direction = + let (x, y) = dir in + let new_dir = + match direction with + | '>' -> (x + 1, y) + | '<' -> (x - 1, y) + | '^' -> (x, y + 1) + | 'v' -> (x, y - 1) + | _ -> raise (Invalid_argument "Expected one of ><^v") + in + table_inc table new_dir; + new_dir + +let rec move_all table current directions = + match directions with + | [] -> () + | x::xs -> + let new_dir = move_direction table current x in + move_all table new_dir xs + +let table_merge t1 t2 = + (* Stolen from https://stackoverflow.com/a/78427785/26861165 *) + t2 + |> Hashtbl.to_seq + |> Hashtbl.replace_seq t1; + () + +let () = + let characters = read_all "3-input" in + let table = Hashtbl.create 2081 in + table_inc table (0, 0); + move_all table (0, 0) characters; + Printf.printf "Round 1: %d\n" (Hashtbl.length table); + + let santa = Hashtbl.create 1024 in + let robosanta = Hashtbl.create 1024 in + table_inc santa (0, 0); + table_inc robosanta (0, 0); + + let santa_filter i _ = i mod 2 == 0 in + let robosanta_filter i _ = i mod 2 == 1 in + let santa_dirs = List.filteri santa_filter characters in + let robosanta_dirs = List.filteri robosanta_filter characters in + + move_all santa (0, 0) santa_dirs; + move_all robosanta (0, 0) robosanta_dirs; + table_merge santa robosanta; + Printf.printf "Round 2: %d\n" (Hashtbl.length santa); + +(* Local Variables: *) +(* compile-command: "ocaml puzzle-3.ml" *) +(* End: *) -- cgit v1.2.3-13-gbd6f