move Grid into its own file
This commit is contained in:
parent
1d60878428
commit
88acb381f1
16
src/day12.ml
16
src/day12.ml
|
|
@ -15,10 +15,10 @@ let parse_grid start_anywhere =
|
||||||
let unvisited = ref [] in
|
let unvisited = ref [] in
|
||||||
let grid =
|
let grid =
|
||||||
Utils.lines_of_input 12
|
Utils.lines_of_input 12
|
||||||
|> Vec2.parse_grid (fun char -> { char; visited = false; distance = infinity })
|
|> Grid.of_lines (fun char -> { char; visited = false; distance = infinity })
|
||||||
in
|
in
|
||||||
Vec2.iter_grid grid (fun pos ->
|
Grid.iter grid (fun pos ->
|
||||||
let n = Vec2.at_e grid pos in
|
let n = Grid.at_e grid pos in
|
||||||
match n.char with
|
match n.char with
|
||||||
| 'E' -> e := pos
|
| 'E' -> e := pos
|
||||||
| 'S' ->
|
| 'S' ->
|
||||||
|
|
@ -42,11 +42,11 @@ let reachable f t =
|
||||||
;;
|
;;
|
||||||
|
|
||||||
let rec path grid goal current unvisited =
|
let rec path grid goal current unvisited =
|
||||||
let current_node = Vec2.at_e grid current in
|
let current_node = Grid.at_e grid current in
|
||||||
Vec2.directions
|
Vec2.directions
|
||||||
|> List.map (fun dir -> Vec2.(current + dir))
|
|> List.map (fun dir -> Vec2.(current + dir))
|
||||||
|> List.iter (fun neighbor ->
|
|> List.iter (fun neighbor ->
|
||||||
match Vec2.at grid neighbor with
|
match Grid.at grid neighbor with
|
||||||
| Some node when (not node.visited) && reachable current_node.char node.char ->
|
| Some node when (not node.visited) && reachable current_node.char node.char ->
|
||||||
let new_distance = current_node.distance + 1 in
|
let new_distance = current_node.distance + 1 in
|
||||||
if new_distance < node.distance then node.distance <- new_distance;
|
if new_distance < node.distance then node.distance <- new_distance;
|
||||||
|
|
@ -57,12 +57,12 @@ let rec path grid goal current unvisited =
|
||||||
unvisited
|
unvisited
|
||||||
:= List.sort
|
:= List.sort
|
||||||
(fun a b ->
|
(fun a b ->
|
||||||
let a = Vec2.at_e grid a in
|
let a = Grid.at_e grid a in
|
||||||
let b = Vec2.at_e grid b in
|
let b = Grid.at_e grid b in
|
||||||
a.distance - b.distance)
|
a.distance - b.distance)
|
||||||
!unvisited;
|
!unvisited;
|
||||||
match !unvisited with
|
match !unvisited with
|
||||||
| shortest :: _ when Vec2.(shortest = goal) -> Vec2.at grid shortest
|
| shortest :: _ when Vec2.(shortest = goal) -> Grid.at grid shortest
|
||||||
| shortest :: rest -> path grid goal shortest @@ ref rest
|
| shortest :: rest -> path grid goal shortest @@ ref rest
|
||||||
| [] -> None
|
| [] -> None
|
||||||
;;
|
;;
|
||||||
|
|
|
||||||
14
src/day8.ml
14
src/day8.ml
|
|
@ -1,17 +1,17 @@
|
||||||
open Containers
|
open Containers
|
||||||
|
|
||||||
let parse_grid () =
|
let parse_grid () =
|
||||||
Vec2.parse_grid Fun.(Char.to_string %> int_of_string) @@ Utils.lines_of_input 8
|
Grid.of_lines Fun.(Char.to_string %> int_of_string) @@ Utils.lines_of_input 8
|
||||||
;;
|
;;
|
||||||
|
|
||||||
let part1 () =
|
let part1 () =
|
||||||
let grid = parse_grid () in
|
let grid = parse_grid () in
|
||||||
let num_visible = ref 0 in
|
let num_visible = ref 0 in
|
||||||
Vec2.iter_grid grid (fun start ->
|
Grid.iter grid (fun start ->
|
||||||
let start_height = Option.get_exn_or "unreachable" @@ Vec2.at grid start in
|
let start_height = Option.get_exn_or "unreachable" @@ Grid.at grid start in
|
||||||
let rec walk_shorter_trees start step =
|
let rec walk_shorter_trees start step =
|
||||||
let next = Vec2.(start + step) in
|
let next = Vec2.(start + step) in
|
||||||
match Vec2.at grid next with
|
match Grid.at grid next with
|
||||||
| Some height when height < start_height -> walk_shorter_trees next step
|
| Some height when height < start_height -> walk_shorter_trees next step
|
||||||
| opt -> opt
|
| opt -> opt
|
||||||
in
|
in
|
||||||
|
|
@ -28,11 +28,11 @@ let part1 () =
|
||||||
let part2 () =
|
let part2 () =
|
||||||
let grid = parse_grid () in
|
let grid = parse_grid () in
|
||||||
let best_score = ref 0 in
|
let best_score = ref 0 in
|
||||||
Vec2.iter_grid grid (fun start ->
|
Grid.iter grid (fun start ->
|
||||||
let start_height = Option.get_exn_or "unreachable" @@ Vec2.at grid start in
|
let start_height = Option.get_exn_or "unreachable" @@ Grid.at grid start in
|
||||||
let rec trees_in_view start in_view step =
|
let rec trees_in_view start in_view step =
|
||||||
let next = Vec2.(start + step) in
|
let next = Vec2.(start + step) in
|
||||||
match Vec2.at grid next with
|
match Grid.at grid next with
|
||||||
| Some height when height < start_height -> trees_in_view next (in_view + 1) step
|
| Some height when height < start_height -> trees_in_view next (in_view + 1) step
|
||||||
| Some _ -> in_view + 1
|
| Some _ -> in_view + 1
|
||||||
| None -> in_view
|
| None -> in_view
|
||||||
|
|
|
||||||
63
src/grid.ml
Normal file
63
src/grid.ml
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
open Containers
|
||||||
|
open Vec2
|
||||||
|
|
||||||
|
type 'a t =
|
||||||
|
{ width : int
|
||||||
|
; height : int
|
||||||
|
; items : 'a array
|
||||||
|
}
|
||||||
|
[@@deriving show]
|
||||||
|
|
||||||
|
let grid_vec2_of_idx ~width ~idx =
|
||||||
|
let y = idx / width in
|
||||||
|
let x = idx mod width in
|
||||||
|
Vec2.of_tuple (x, y)
|
||||||
|
;;
|
||||||
|
|
||||||
|
let at (grid : 'a t) (point : Vec2.t) =
|
||||||
|
let x, y = Vec2.to_tuple point in
|
||||||
|
if x >= 0 && x < grid.width && y >= 0 && y < grid.height
|
||||||
|
then Array.get_safe grid.items @@ Int.((grid.width * y) + x)
|
||||||
|
else None
|
||||||
|
;;
|
||||||
|
|
||||||
|
let at_e (grid : 'a t) (point : Vec2.t) =
|
||||||
|
Option.get_exn_or "out of bounds!" @@ at grid point
|
||||||
|
;;
|
||||||
|
|
||||||
|
let find (grid : 'a t) pred =
|
||||||
|
let open Option.Infix in
|
||||||
|
let* idx, item = Array.find_idx pred grid.items in
|
||||||
|
Some (grid_vec2_of_idx ~width:grid.width ~idx, item)
|
||||||
|
;;
|
||||||
|
|
||||||
|
let init ~width ~height init =
|
||||||
|
{ width
|
||||||
|
; height
|
||||||
|
; items = Array.init (width * height) (fun idx -> init @@ grid_vec2_of_idx ~width ~idx)
|
||||||
|
}
|
||||||
|
;;
|
||||||
|
|
||||||
|
let of_lines parse_char lines : 'a t =
|
||||||
|
match lines with
|
||||||
|
| first_line :: _ ->
|
||||||
|
let width = String.length first_line in
|
||||||
|
let height = List.length lines in
|
||||||
|
let yeet =
|
||||||
|
lines
|
||||||
|
|> List.map String.to_list
|
||||||
|
|> List.flatten
|
||||||
|
|> List.map parse_char
|
||||||
|
|> Array.of_list
|
||||||
|
in
|
||||||
|
{ width; height; items = yeet }
|
||||||
|
| _ -> failwith "somethin fucd up"
|
||||||
|
;;
|
||||||
|
|
||||||
|
let iter grid callback =
|
||||||
|
for y = 0 to Int.(grid.height - 1) do
|
||||||
|
for x = 0 to Int.(grid.width - 1) do
|
||||||
|
callback @@ Vec2.of_tuple (x, y)
|
||||||
|
done
|
||||||
|
done
|
||||||
|
;;
|
||||||
8
src/grid.mli
Normal file
8
src/grid.mli
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
type 'a t [@@deriving show]
|
||||||
|
|
||||||
|
val at : 'a t -> Vec2.t -> 'a option
|
||||||
|
val at_e : 'a t -> Vec2.t -> 'a
|
||||||
|
val init : width:int -> height:int -> (Vec2.t -> 'a) -> 'a t
|
||||||
|
val of_lines : (char -> 'a) -> string list -> 'a t
|
||||||
|
val find : 'a t -> ('a -> bool) -> (Vec2.t * 'a) option
|
||||||
|
val iter : 'a t -> (Vec2.t -> unit) -> unit
|
||||||
61
src/vec2.ml
61
src/vec2.ml
|
|
@ -2,13 +2,6 @@ open Containers
|
||||||
|
|
||||||
type t = int * int [@@deriving show]
|
type t = int * int [@@deriving show]
|
||||||
|
|
||||||
type 'a grid =
|
|
||||||
{ width : int
|
|
||||||
; height : int
|
|
||||||
; items : 'a array
|
|
||||||
}
|
|
||||||
[@@deriving show]
|
|
||||||
|
|
||||||
let origin = 0, 0
|
let origin = 0, 0
|
||||||
let up = 0, 1
|
let up = 0, 1
|
||||||
let down = 0, -1
|
let down = 0, -1
|
||||||
|
|
@ -20,57 +13,3 @@ 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.map_same2 ( - ) a b
|
let ( - ) a b = Pair.map_same2 ( - ) a b
|
||||||
let ( = ) a b = Pair.equal ( = ) ( = ) a b
|
let ( = ) a b = Pair.equal ( = ) ( = ) a b
|
||||||
|
|
||||||
let grid_vec2_of_idx ~width ~idx =
|
|
||||||
let y = idx / width in
|
|
||||||
let x = idx mod width in
|
|
||||||
x, y
|
|
||||||
;;
|
|
||||||
|
|
||||||
let at (grid : 'a grid) (point : t) =
|
|
||||||
let x, y = point in
|
|
||||||
if x >= 0 && x < grid.width && y >= 0 && y < grid.height
|
|
||||||
then Array.get_safe grid.items @@ Int.((grid.width * y) + x)
|
|
||||||
else None
|
|
||||||
;;
|
|
||||||
|
|
||||||
let at_e (grid : 'a grid) (point : t) =
|
|
||||||
Option.get_exn_or "out of bounds!" @@ at grid point
|
|
||||||
;;
|
|
||||||
|
|
||||||
let find (grid : 'a grid) pred =
|
|
||||||
let open Option.Infix in
|
|
||||||
let* idx, item = Array.find_idx pred grid.items in
|
|
||||||
Some (grid_vec2_of_idx ~width:grid.width ~idx, item)
|
|
||||||
;;
|
|
||||||
|
|
||||||
let init_grid ~width ~height init =
|
|
||||||
{ width
|
|
||||||
; height
|
|
||||||
; items = Array.init (width * height) (fun idx -> init @@ grid_vec2_of_idx ~width ~idx)
|
|
||||||
}
|
|
||||||
;;
|
|
||||||
|
|
||||||
let parse_grid parse_char lines : 'a grid =
|
|
||||||
match lines with
|
|
||||||
| first_line :: _ ->
|
|
||||||
let width = String.length first_line in
|
|
||||||
let height = List.length lines in
|
|
||||||
let yeet =
|
|
||||||
lines
|
|
||||||
|> List.map String.to_list
|
|
||||||
|> List.flatten
|
|
||||||
|> List.map parse_char
|
|
||||||
|> Array.of_list
|
|
||||||
in
|
|
||||||
{ width; height; items = yeet }
|
|
||||||
| _ -> failwith "somethin fucd up"
|
|
||||||
;;
|
|
||||||
|
|
||||||
let iter_grid (grid : 'a grid) callback =
|
|
||||||
for y = 0 to Int.(grid.height - 1) do
|
|
||||||
for x = 0 to Int.(grid.width - 1) do
|
|
||||||
callback (x, y)
|
|
||||||
done
|
|
||||||
done
|
|
||||||
;;
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
type t [@@deriving show]
|
type t [@@deriving show]
|
||||||
type 'a grid [@@deriving show]
|
|
||||||
|
|
||||||
val origin : t
|
val origin : t
|
||||||
val up : t
|
val up : t
|
||||||
|
|
@ -12,9 +11,3 @@ val to_tuple : t -> int * int
|
||||||
val ( + ) : t -> t -> t
|
val ( + ) : t -> t -> t
|
||||||
val ( - ) : t -> t -> t
|
val ( - ) : t -> t -> t
|
||||||
val ( = ) : t -> t -> bool
|
val ( = ) : t -> t -> bool
|
||||||
val at : 'a grid -> t -> 'a option
|
|
||||||
val at_e : 'a grid -> t -> 'a
|
|
||||||
val init_grid : width:int -> height:int -> (t -> 'a) -> 'a grid
|
|
||||||
val parse_grid : (char -> 'a) -> string list -> 'a grid
|
|
||||||
val find : 'a grid -> ('a -> bool) -> (t * 'a) option
|
|
||||||
val iter_grid : 'a grid -> (t -> unit) -> unit
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user