Finish puzzle 3 of 2015 in ocaml
This commit is contained in:
71
2015/puzzle-3.ml
Normal file
71
2015/puzzle-3.ml
Normal file
@@ -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: *)
|
||||
Reference in New Issue
Block a user