blob: ae7663efba14a4a98af0186d92c3951a29c7b51f (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
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: *)
|