solve day 18!
it was kinda ez
This commit is contained in:
parent
1904239ca7
commit
8ec58edd08
2025
inputs/day18.tt
Normal file
2025
inputs/day18.tt
Normal file
File diff suppressed because it is too large
Load Diff
|
|
@ -37,7 +37,8 @@ let reachable f t =
|
||||||
let get_neighbors grid node_pos =
|
let get_neighbors grid node_pos =
|
||||||
let node = Grid.at_e grid node_pos in
|
let node = Grid.at_e grid node_pos in
|
||||||
Vec2.directions
|
Vec2.directions
|
||||||
|> List.filter_map (fun dir ->
|
|> Iter.of_list
|
||||||
|
|> Iter.filter_map (fun dir ->
|
||||||
let neighbor_pos = Vec2.(node_pos + dir) in
|
let neighbor_pos = Vec2.(node_pos + dir) in
|
||||||
match Grid.at grid neighbor_pos with
|
match Grid.at grid neighbor_pos with
|
||||||
| Some neighbor when reachable node.char neighbor.char -> Some neighbor_pos
|
| Some neighbor when reachable node.char neighbor.char -> Some neighbor_pos
|
||||||
|
|
|
||||||
|
|
@ -47,9 +47,10 @@ let parse_valves lines =
|
||||||
~get_weight:(fun _ _ -> 1)
|
~get_weight:(fun _ _ -> 1)
|
||||||
~get_neighbors:(fun room ->
|
~get_neighbors:(fun room ->
|
||||||
match Hashtbl.get rooms room with
|
match Hashtbl.get rooms room with
|
||||||
| Some (_, tunnels) -> tunnels
|
| Some (_, tunnels) -> Iter.of_list tunnels
|
||||||
| None -> failwith "sad")
|
| None -> failwith "sad")
|
||||||
~start_nodes:[ from ]
|
~start_nodes:[ from ]
|
||||||
|
()
|
||||||
%> Option.get_exn_or "big sad")
|
%> Option.get_exn_or "big sad")
|
||||||
in
|
in
|
||||||
valves
|
valves
|
||||||
|
|
|
||||||
121
src/day18.ml
Normal file
121
src/day18.ml
Normal file
|
|
@ -0,0 +1,121 @@
|
||||||
|
open Containers
|
||||||
|
|
||||||
|
let example_lines =
|
||||||
|
String.lines
|
||||||
|
{|2,2,2
|
||||||
|
1,2,2
|
||||||
|
3,2,2
|
||||||
|
2,1,2
|
||||||
|
2,3,2
|
||||||
|
2,2,1
|
||||||
|
2,2,3
|
||||||
|
2,2,4
|
||||||
|
2,2,6
|
||||||
|
1,2,5
|
||||||
|
3,2,5
|
||||||
|
2,1,5
|
||||||
|
2,3,5|}
|
||||||
|
;;
|
||||||
|
|
||||||
|
module Vec3 = struct
|
||||||
|
type t = int * int * int [@@deriving show, eq, ord, hash]
|
||||||
|
|
||||||
|
let directions = [ 1, 0, 0; -1, 0, 0; 0, 1, 0; 0, -1, 0; 0, 0, 1; 0, 0, -1 ]
|
||||||
|
let ( + ) (x1, y1, z1) (x2, y2, z2) = x1 + x2, y1 + y2, z1 + z2
|
||||||
|
let ( - ) (x1, y1, z1) (x2, y2, z2) = x1 - x2, y1 - y2, z1 - z2
|
||||||
|
let ( = ) = equal
|
||||||
|
|
||||||
|
let iter_region (ax, ay, az) (bx, by, bz) callback =
|
||||||
|
for z = az to bz do
|
||||||
|
for y = ay to by do
|
||||||
|
for x = ax to bx do
|
||||||
|
let p = x, y, z in
|
||||||
|
callback p
|
||||||
|
done
|
||||||
|
done
|
||||||
|
done
|
||||||
|
;;
|
||||||
|
|
||||||
|
let in_bounds (lx, ly, lz) (hx, hy, hz) (x, y, z) =
|
||||||
|
not (x < lx || x > hx || y < ly || y > hy || z < lz || z > hz)
|
||||||
|
;;
|
||||||
|
|
||||||
|
let find_bounds points =
|
||||||
|
let first = Iter.head_exn points in
|
||||||
|
let padding = 1, 1, 1 in
|
||||||
|
let min, max =
|
||||||
|
points
|
||||||
|
|> Iter.drop 1
|
||||||
|
|> Iter.fold
|
||||||
|
(fun ((lx, ly, lz), (hx, hy, hz)) (x, y, z) ->
|
||||||
|
(min lx x, min ly y, min lz z), (max hx x, max hy y, max hz z))
|
||||||
|
(first, first)
|
||||||
|
in
|
||||||
|
min - padding, max + padding
|
||||||
|
;;
|
||||||
|
end
|
||||||
|
|
||||||
|
module Vec3Set = Set.Make (Vec3)
|
||||||
|
|
||||||
|
let parse_points lines =
|
||||||
|
lines
|
||||||
|
|> List.map (fun line ->
|
||||||
|
match List.map Int.of_string_exn Re.(matches (Pcre.regexp {|\d+|}) line) with
|
||||||
|
| [ x; y; z ] -> x, y, z
|
||||||
|
| _ -> failwith "oopzi doopers")
|
||||||
|
|> Vec3Set.of_list
|
||||||
|
;;
|
||||||
|
|
||||||
|
let solve_part_1 lines =
|
||||||
|
let points = parse_points lines in
|
||||||
|
let min, max = Vec3.find_bounds @@ Vec3Set.to_iter points in
|
||||||
|
let surface_area = ref 0 in
|
||||||
|
Vec3.iter_region min max (fun point ->
|
||||||
|
if not @@ Vec3Set.mem point points
|
||||||
|
then
|
||||||
|
Vec3.directions
|
||||||
|
|> List.iter (fun dir ->
|
||||||
|
let n = Vec3.(point + dir) in
|
||||||
|
if Vec3Set.mem n points then incr surface_area));
|
||||||
|
!surface_area
|
||||||
|
;;
|
||||||
|
|
||||||
|
let%expect_test "Day 18.1 example" =
|
||||||
|
Format.printf "%i" @@ solve_part_1 example_lines;
|
||||||
|
[%expect {| 64 |}]
|
||||||
|
;;
|
||||||
|
|
||||||
|
let%expect_test "Day 18.1" =
|
||||||
|
Format.printf "%i" @@ solve_part_1 @@ Utils.lines_of_input 18;
|
||||||
|
[%expect {| 3662 |}]
|
||||||
|
;;
|
||||||
|
|
||||||
|
let solve_part_2 lines =
|
||||||
|
let points = parse_points lines in
|
||||||
|
let min, max = Vec3.find_bounds @@ Vec3Set.to_iter points in
|
||||||
|
let in_bounds = Vec3.in_bounds min max in
|
||||||
|
let surface_area = ref 0 in
|
||||||
|
let directions_iter = Iter.of_list Vec3.directions in
|
||||||
|
let get_neighbors point =
|
||||||
|
directions_iter
|
||||||
|
|> Iter.map Vec3.(fun dir -> point + dir)
|
||||||
|
|> Iter.filter (fun neighbor ->
|
||||||
|
let in_droplet = Vec3Set.mem neighbor points in
|
||||||
|
if in_droplet then incr surface_area;
|
||||||
|
(not in_droplet) && in_bounds neighbor)
|
||||||
|
in
|
||||||
|
let _ignore =
|
||||||
|
Utils.djikstra_hash ~get_weight:(fun _ _ -> 1) ~get_neighbors ~start_nodes:[ min ] ()
|
||||||
|
in
|
||||||
|
!surface_area
|
||||||
|
;;
|
||||||
|
|
||||||
|
let%expect_test "Day 18.2 example" =
|
||||||
|
Format.printf "%i" @@ solve_part_2 example_lines;
|
||||||
|
[%expect {| 58 |}]
|
||||||
|
;;
|
||||||
|
|
||||||
|
let%expect_test "Day 18.2" =
|
||||||
|
Format.printf "%i" @@ solve_part_2 @@ Utils.lines_of_input 18;
|
||||||
|
[%expect {| 2060 |}]
|
||||||
|
;;
|
||||||
|
|
@ -50,7 +50,7 @@ let djikstra ~eq ~get_info ~set_info ~get_weight ~get_neighbors ~goal ~start_nod
|
||||||
let c_dist, _ = get_info c_node in
|
let c_dist, _ = get_info c_node in
|
||||||
set_info c_node (c_dist, true);
|
set_info c_node (c_dist, true);
|
||||||
get_neighbors c_node
|
get_neighbors c_node
|
||||||
|> List.iter (fun neighbor ->
|
|> Iter.iter (fun neighbor ->
|
||||||
let n_dist, n_visited = get_info neighbor in
|
let n_dist, n_visited = get_info neighbor in
|
||||||
if not n_visited
|
if not n_visited
|
||||||
then (
|
then (
|
||||||
|
|
@ -90,6 +90,7 @@ let djikstra_hash
|
||||||
~get_weight
|
~get_weight
|
||||||
~get_neighbors
|
~get_neighbors
|
||||||
~start_nodes
|
~start_nodes
|
||||||
|
()
|
||||||
=
|
=
|
||||||
let module Tbl =
|
let module Tbl =
|
||||||
CCHashtbl.Make (struct
|
CCHashtbl.Make (struct
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user