parse day 15

This commit is contained in:
ryan committed 2023-11-08 09:14:00 -08:00
1 parent 724576d120
commit dcb1338aa3
5 files changed
+114 -2

No files matched your search

+65
View File
@@ -0,0 +1,65 @@
open Containers
type sensor =
{ pos : Vec2.t
; beacon : Vec2.t
; dist : int
}
[@@deriving show { with_path = false }]
let taxicab_dist a b =
let x, y = Vec2.(abs (a - b) |> to_tuple) in
x + y
;;
let parse_sensor line =
let open Utils.Parse in
let parse =
many1 (not_int *> int)
>>= function
| [ sx; sy; bx; by ] ->
let pos = Vec2.of_tuple (sx, sy) in
let beacon = Vec2.of_tuple (bx, by) in
return { pos; beacon; dist = taxicab_dist pos beacon }
| _ -> failwith "should be four ints"
in
Result.get_or_failwith @@ parse_string ~consume:All parse line
;;
let example_lines =
[ "Sensor at x=2, y=18: closest beacon is at x=-2, y=15"
; "Sensor at x=9, y=16: closest beacon is at x=10, y=16"
; "Sensor at x=13, y=2: closest beacon is at x=15, y=3"
; "Sensor at x=12, y=14: closest beacon is at x=10, y=16"
; "Sensor at x=10, y=20: closest beacon is at x=10, y=16"
; "Sensor at x=14, y=17: closest beacon is at x=10, y=16"
; "Sensor at x=8, y=7: closest beacon is at x=2, y=10"
; "Sensor at x=2, y=0: closest beacon is at x=2, y=10"
; "Sensor at x=0, y=11: closest beacon is at x=2, y=10"
; "Sensor at x=20, y=14: closest beacon is at x=25, y=17"
; "Sensor at x=17, y=20: closest beacon is at x=21, y=22"
; "Sensor at x=16, y=7: closest beacon is at x=15, y=3"
; "Sensor at x=14, y=3: closest beacon is at x=15, y=3"
; "Sensor at x=20, y=1: closest beacon is at x=15, y=3"
]
;;
let%expect_test "Day 15 example" =
example_lines |> List.map parse_sensor |> List.iter @@ Format.printf "%a@ " pp_sensor;
[%expect
{|
{ pos = { Vec2.x = 2; y = 18 }; beacon = { Vec2.x = -2; y = 15 }; dist = 7 }
{ pos = { Vec2.x = 9; y = 16 }; beacon = { Vec2.x = 10; y = 16 }; dist = 1 }
{ pos = { Vec2.x = 13; y = 2 }; beacon = { Vec2.x = 15; y = 3 }; dist = 3 }
{ pos = { Vec2.x = 12; y = 14 }; beacon = { Vec2.x = 10; y = 16 }; dist = 4 }
{ pos = { Vec2.x = 10; y = 20 }; beacon = { Vec2.x = 10; y = 16 }; dist = 4 }
{ pos = { Vec2.x = 14; y = 17 }; beacon = { Vec2.x = 10; y = 16 }; dist = 5 }
{ pos = { Vec2.x = 8; y = 7 }; beacon = { Vec2.x = 2; y = 10 }; dist = 9 }
{ pos = { Vec2.x = 2; y = 0 }; beacon = { Vec2.x = 2; y = 10 }; dist = 10 }
{ pos = { Vec2.x = 0; y = 11 }; beacon = { Vec2.x = 2; y = 10 }; dist = 3 }
{ pos = { Vec2.x = 20; y = 14 }; beacon = { Vec2.x = 25; y = 17 }; dist = 8 }
{ pos = { Vec2.x = 17; y = 20 }; beacon = { Vec2.x = 21; y = 22 }; dist = 6 }
{ pos = { Vec2.x = 16; y = 7 }; beacon = { Vec2.x = 15; y = 3 }; dist = 5 }
{ pos = { Vec2.x = 14; y = 3 }; beacon = { Vec2.x = 15; y = 3 }; dist = 1 }
{ pos = { Vec2.x = 20; y = 1 }; beacon = { Vec2.x = 15; y = 3 }; dist = 7 } |}]
;;
+11 -2
View File
@@ -13,11 +13,20 @@ let lines_of_input day =
module Parse = struct
include Angstrom
let int =
let sign = option 1 (char '-' >>= fun _ -> return (-1))
let digits =
take_while1 (function
| '0' .. '9' -> true
| _ -> false)
>>| int_of_string
<?> "int"
;;
let int = map2 sign digits ~f:( * )
let not_int =
skip_while (function
| '0' .. '9' | '-' -> false
| _ -> true)
;;
end
+1
View File
@@ -17,3 +17,4 @@ let to_tuple { x; y } = x, y
let ( + ) a b = { x = a.x + b.x; y = a.y + b.y }
let ( - ) a b = { x = a.x - b.x; y = a.y - b.y }
let ( = ) a b = a.x = b.x && a.y = b.y
let abs a = Int.{ x = abs a.x; y = abs a.y }
+1
View File
@@ -15,3 +15,4 @@ val to_tuple : t -> int * int
val ( + ) : t -> t -> t
val ( - ) : t -> t -> t
val ( = ) : t -> t -> bool
val abs : t -> t