move Grid into its own file

This commit is contained in:
ryan 2023-10-31 15:12:11 -07:00
parent 1d60878428
commit 88acb381f1
6 changed files with 86 additions and 83 deletions

View File

@ -15,10 +15,10 @@ let parse_grid start_anywhere =
let unvisited = ref [] in
let grid =
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
Vec2.iter_grid grid (fun pos ->
let n = Vec2.at_e grid pos in
Grid.iter grid (fun pos ->
let n = Grid.at_e grid pos in
match n.char with
| 'E' -> e := pos
| 'S' ->
@ -42,11 +42,11 @@ let reachable f t =
;;
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
|> List.map (fun dir -> Vec2.(current + dir))
|> 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 ->
let new_distance = current_node.distance + 1 in
if new_distance < node.distance then node.distance <- new_distance;
@ -57,12 +57,12 @@ let rec path grid goal current unvisited =
unvisited
:= List.sort
(fun a b ->
let a = Vec2.at_e grid a in
let b = Vec2.at_e grid b in
let a = Grid.at_e grid a in
let b = Grid.at_e grid b in
a.distance - b.distance)
!unvisited;
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
| [] -> None
;;

View File

@ -1,17 +1,17 @@
open Containers
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 grid = parse_grid () in
let num_visible = ref 0 in
Vec2.iter_grid grid (fun start ->
let start_height = Option.get_exn_or "unreachable" @@ Vec2.at grid start in
Grid.iter grid (fun start ->
let start_height = Option.get_exn_or "unreachable" @@ Grid.at grid start in
let rec walk_shorter_trees start step =
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
| opt -> opt
in
@ -28,11 +28,11 @@ let part1 () =
let part2 () =
let grid = parse_grid () in
let best_score = ref 0 in
Vec2.iter_grid grid (fun start ->
let start_height = Option.get_exn_or "unreachable" @@ Vec2.at grid start in
Grid.iter grid (fun start ->
let start_height = Option.get_exn_or "unreachable" @@ Grid.at grid start in
let rec trees_in_view start in_view step =
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 _ -> in_view + 1
| None -> in_view

63
src/grid.ml Normal file
View 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
View 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

View File

@ -2,13 +2,6 @@ open Containers
type t = int * int [@@deriving show]
type 'a grid =
{ width : int
; height : int
; items : 'a array
}
[@@deriving show]
let origin = 0, 0
let up = 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.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
;;

View File

@ -1,5 +1,4 @@
type t [@@deriving show]
type 'a grid [@@deriving show]
val origin : 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 -> 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