80 lines
2.4 KiB
OCaml
80 lines
2.4 KiB
OCaml
let pos_of_numeric_grid c =
|
|
match c with
|
|
| '7' -> (0, 0)
|
|
| '8' -> (1, 0)
|
|
| '9' -> (2, 0)
|
|
| '4' -> (0, 1)
|
|
| '5' -> (1, 1)
|
|
| '6' -> (2, 1)
|
|
| '1' -> (0, 2)
|
|
| '2' -> (1, 2)
|
|
| '3' -> (2, 2)
|
|
| '0' -> (1, 3)
|
|
| 'A' -> (2, 3)
|
|
| _ -> raise (invalid_arg "pos_of_numeric_grid")
|
|
|
|
let pos_of_dir_grid c =
|
|
match c with
|
|
| '^' -> (1, 3)
|
|
| 'A' -> (2, 3)
|
|
| '<' -> (0, 4)
|
|
| 'v' -> (1, 4)
|
|
| '>' -> (2, 4)
|
|
| _ -> raise (invalid_arg "pos_of_dir_grid")
|
|
|
|
let invalid_x, invalid_y = (0, 3)
|
|
|
|
let rec move pos_of_grid builder (cx, cy) code =
|
|
match Seq.uncons code with
|
|
| None -> Buffer.contents builder
|
|
| Some (c, t) ->
|
|
let dx, dy = pos_of_grid c in
|
|
if dx > cx && (cy = dy || cy <> invalid_y) then begin
|
|
Buffer.add_string builder (String.make (dx - cx) '>');
|
|
move pos_of_grid builder (dx, cy) code
|
|
end
|
|
else if dx < cx && (cy = dy || cy <> invalid_y) then begin
|
|
Buffer.add_string builder (String.make (cx - dx) '<');
|
|
move pos_of_grid builder (dx, cy) code
|
|
end
|
|
else if dy > cy && (cx = dx || cx <> invalid_x) then begin
|
|
Buffer.add_string builder (String.make (dy - cy) 'v');
|
|
move pos_of_grid builder (cx, dy) code
|
|
end
|
|
else if dy < cy && (cx = dx || cx <> invalid_x) then begin
|
|
Buffer.add_string builder (String.make (cy - dy) '^');
|
|
move pos_of_grid builder (cx, dy) code
|
|
end
|
|
else begin
|
|
assert (cx = dx);
|
|
assert (dy = dy);
|
|
Buffer.add_char builder 'A';
|
|
move pos_of_grid builder (cx, cy) t
|
|
end
|
|
|
|
let process_code pos_of_grid code =
|
|
let builder = Buffer.create 30 in
|
|
move pos_of_grid builder (pos_of_grid 'A') (String.to_seq code)
|
|
|
|
let human_insns code =
|
|
let first_robot_insns = process_code pos_of_numeric_grid code in
|
|
let second_robot_insns = process_code pos_of_dir_grid first_robot_insns in
|
|
let human = process_code pos_of_dir_grid second_robot_insns in
|
|
print_endline human;
|
|
print_endline second_robot_insns;
|
|
print_endline first_robot_insns;
|
|
print_endline code;
|
|
human
|
|
|
|
let complexity code =
|
|
let insns = human_insns code in
|
|
let num = int_of_string (String.sub code 0 (String.length code - 1)) in
|
|
Printf.printf "%s (%d): %s (%d) (%d) \n" code num insns (String.length insns)
|
|
(num * String.length insns);
|
|
num * String.length insns
|
|
|
|
let part1 codes = List.map complexity codes |> List.fold_left ( + ) 0
|
|
let _ = Aoc.main Aoc.strings_of_file [ (string_of_int, part1) ]
|
|
|
|
(* 175386 too high *)
|