Compare commits
2
Commits
239af2f93b
...
1ee3a5a3c5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1ee3a5a3c5 | ||
|
|
5e1c30637e |
No files matched your search
@@ -0,0 +1 @@
|
|||||||
|
#install_printer Aoc.Vec2.pp;;
|
||||||
+2
-1
@@ -8,5 +8,6 @@ let () =
|
|||||||
Day5.print ();
|
Day5.print ();
|
||||||
Day6.print ();
|
Day6.print ();
|
||||||
Day7.print ();
|
Day7.print ();
|
||||||
Day8.print ()
|
Day8.print ();
|
||||||
|
Day9.print ()
|
||||||
;;
|
;;
|
||||||
+2000
File diff suppressed because it is too large.
Load diff
+3
-23
@@ -1,28 +1,8 @@
|
|||||||
open Containers
|
open Containers
|
||||||
|
|
||||||
module Vec2 : sig
|
(* module Vec2 : sig *)
|
||||||
type t
|
(* end = struct *)
|
||||||
|
(* end *)
|
||||||
val directions : t list
|
|
||||||
val of_tuple : int * int -> t
|
|
||||||
val to_tuple : t -> int * int
|
|
||||||
val ( + ) : t -> t -> t
|
|
||||||
val at : 'a array array -> t -> 'a option
|
|
||||||
end = struct
|
|
||||||
type t = int * int
|
|
||||||
|
|
||||||
let directions = [ 1, 0; 0, 1; -1, 0; 0, -1 ]
|
|
||||||
let of_tuple x = x
|
|
||||||
let to_tuple x = x
|
|
||||||
let ( + ) a b = Pair.map_same2 ( + ) a b
|
|
||||||
|
|
||||||
let at grid point =
|
|
||||||
let x, y = to_tuple point in
|
|
||||||
let open Option.Infix in
|
|
||||||
let* row = Array.get_safe grid y in
|
|
||||||
Array.get_safe row x
|
|
||||||
;;
|
|
||||||
end
|
|
||||||
|
|
||||||
let parse_grid () =
|
let parse_grid () =
|
||||||
let lines = Utils.lines_of_input 8 in
|
let lines = Utils.lines_of_input 8 in
|
||||||
|
|||||||
+68
@@ -0,0 +1,68 @@
|
|||||||
|
open Containers
|
||||||
|
|
||||||
|
let parse_input () =
|
||||||
|
Utils.lines_of_input 9
|
||||||
|
|> List.concat_map (fun line ->
|
||||||
|
match String.split ~by:" " line with
|
||||||
|
| [ dir; count ] ->
|
||||||
|
let count = int_of_string count in
|
||||||
|
let dir =
|
||||||
|
match dir with
|
||||||
|
| "U" -> Vec2.up
|
||||||
|
| "D" -> Vec2.down
|
||||||
|
| "L" -> Vec2.left
|
||||||
|
| "R" -> Vec2.right
|
||||||
|
| _ -> failwith "failed to parse instructions"
|
||||||
|
in
|
||||||
|
List.init count (fun _ -> dir)
|
||||||
|
| _ -> failwith "failed to parse instructions")
|
||||||
|
;;
|
||||||
|
|
||||||
|
let next_pos head tail =
|
||||||
|
let dx, dy = Vec2.(to_tuple @@ (tail - head)) in
|
||||||
|
if abs dx <= 1 && abs dy <= 1
|
||||||
|
then tail
|
||||||
|
else (
|
||||||
|
let x_dir = if dx > 0 then Vec2.right else Vec2.left in
|
||||||
|
let y_dir = if dy > 0 then Vec2.up else Vec2.down in
|
||||||
|
let dir =
|
||||||
|
if abs dx = abs dy
|
||||||
|
then Vec2.(x_dir + y_dir)
|
||||||
|
else if abs dx > abs dy
|
||||||
|
then x_dir
|
||||||
|
else y_dir
|
||||||
|
in
|
||||||
|
Vec2.(head + dir))
|
||||||
|
;;
|
||||||
|
|
||||||
|
let solve length =
|
||||||
|
let moves = parse_input () in
|
||||||
|
let start = Vec2.of_tuple (0, 0) in
|
||||||
|
let tail = List.init (length - 1) (fun _ -> start) in
|
||||||
|
let _, _, last_knot_hist =
|
||||||
|
List.fold_left
|
||||||
|
(fun (head, tail, last_knot_hist) dir ->
|
||||||
|
let new_head = Vec2.(head + dir) in
|
||||||
|
let last_knot, new_tail =
|
||||||
|
List.fold_map
|
||||||
|
(fun head knot ->
|
||||||
|
let new_knot = next_pos head knot in
|
||||||
|
new_knot, new_knot)
|
||||||
|
new_head
|
||||||
|
tail
|
||||||
|
in
|
||||||
|
new_head, new_tail, last_knot :: last_knot_hist)
|
||||||
|
(start, tail, [ start ])
|
||||||
|
moves
|
||||||
|
in
|
||||||
|
last_knot_hist |> List.uniq ~eq:Vec2.( = ) |> List.length
|
||||||
|
;;
|
||||||
|
|
||||||
|
let part1 () = solve 2
|
||||||
|
let part2 () = solve 10
|
||||||
|
|
||||||
|
let print () =
|
||||||
|
Printf.(
|
||||||
|
printf "Day 9.1: %d\n" @@ part1 ();
|
||||||
|
printf "Day 9.2: %d\n" @@ part2 ())
|
||||||
|
;;
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
(library
|
(library
|
||||||
(name aoc)
|
(name aoc)
|
||||||
(libraries re containers dune-site)
|
(libraries re containers dune-site)
|
||||||
(preprocess (pps ppx_regexp)))
|
(preprocess (pps ppx_regexp ppx_deriving.show)))
|
||||||
|
|
||||||
(env
|
(env
|
||||||
(dev
|
(dev
|
||||||
|
|||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
open Containers
|
||||||
|
|
||||||
|
type t = int * int [@@deriving show]
|
||||||
|
|
||||||
|
let up = 0, 1
|
||||||
|
let down = 0, -1
|
||||||
|
let left = -1, 0
|
||||||
|
let right = 1, 0
|
||||||
|
let directions = [ up; down; left; right ]
|
||||||
|
let of_tuple x = x
|
||||||
|
let to_tuple x = x
|
||||||
|
let ( + ) a b = Pair.map_same2 ( + ) a b
|
||||||
|
let ( - ) a b = Pair.map_same2 ( - ) a b
|
||||||
|
let ( = ) a b = Pair.equal ( = ) ( = ) a b
|
||||||
|
|
||||||
|
let at grid point =
|
||||||
|
let x, y = to_tuple point in
|
||||||
|
let open Option.Infix in
|
||||||
|
let* row = Array.get_safe grid y in
|
||||||
|
Array.get_safe row x
|
||||||
|
;;
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
type t [@@deriving show] [@@ocaml.toplevel_printer]
|
||||||
|
|
||||||
|
val up : t
|
||||||
|
val down : t
|
||||||
|
val left : t
|
||||||
|
val right : t
|
||||||
|
val directions : t list
|
||||||
|
val of_tuple : int * int -> t
|
||||||
|
val to_tuple : t -> int * int
|
||||||
|
val ( + ) : t -> t -> t
|
||||||
|
val ( - ) : t -> t -> t
|
||||||
|
val ( = ) : t -> t -> bool
|
||||||
|
val at : 'a array array -> t -> 'a option
|
||||||
Reference in new issue
Block a user