56 lines
1.5 KiB
OCaml
56 lines
1.5 KiB
OCaml
open Containers
|
|
|
|
let parse_grid () =
|
|
Vec2.parse_grid 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
|
|
let rec walk_shorter_trees start step =
|
|
let next = Vec2.(start + step) in
|
|
match Vec2.at grid next with
|
|
| Some height when height < start_height -> walk_shorter_trees next step
|
|
| opt -> opt
|
|
in
|
|
let visible =
|
|
Vec2.directions
|
|
|> List.map @@ walk_shorter_trees start
|
|
|> List.map Option.is_none
|
|
|> List.reduce_exn ( || )
|
|
in
|
|
if visible then incr num_visible);
|
|
!num_visible
|
|
;;
|
|
|
|
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
|
|
let rec trees_in_view start in_view step =
|
|
let next = Vec2.(start + step) in
|
|
match Vec2.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
|
|
in
|
|
let score =
|
|
Vec2.directions |> List.map @@ trees_in_view start 0 |> List.reduce_exn ( * )
|
|
in
|
|
if score > !best_score then best_score := score);
|
|
!best_score
|
|
;;
|
|
|
|
let%expect_test "Day 8.1" =
|
|
Printf.printf "%d" @@ part1 ();
|
|
[%expect {| 1803 |}]
|
|
;;
|
|
|
|
let%expect_test "Day 8.2" =
|
|
Printf.printf "%d" @@ part2 ();
|
|
[%expect {| 268912 |}]
|
|
;;
|