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 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
|
||||
;;
|
||||
|
|
|
|||
14
src/day8.ml
14
src/day8.ml
|
|
@ -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
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 '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
|
||||
;;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user