@@ -6,20 +6,25 @@ open Std.Internal.Parsec.String
6
6
open Std.Internal.Parsec
7
7
open Std (HashSet)
8
8
9
- -- private def inputParser : Parser (List Int) := sorry
9
+ instance : Bind List where bind := List.bind
10
+ instance : Pure List where pure := List.pure
10
11
11
- private def decorateWithCoordinates (s: String): List (Point × Char) :=
12
- s.splitOn "\n " |>.enum |>.bind (λ ⟨y, line⟩ =>
13
- line.toList.enum.map (λ ⟨ x, c⟩ => (⟨x, y⟩, c))
14
- )
12
+ private def decorateWithCoordinates (s: String): List (Point × Char) := do
13
+ let (y, line) <- s.splitOn "\n " |> .enum
14
+ let ( x, c) <- line.toList.enum
15
+ pure (⟨x, y⟩, c )
15
16
16
17
def parseInput (s: String): Except String PuzzleInput := do
17
18
let decoratedChars := decorateWithCoordinates s
18
19
let obstacles := decoratedChars.filterMap (λ ⟨p, c⟩ => (c == '#' ).toOption p) |>.toSet
19
20
let start <- decoratedChars.filterMap (λ ⟨p, c⟩ => (c == '^' ).toOption p) |>.head? |>.getOrThrow "no start found"
20
21
let (xs, ys) := decoratedChars.map (·.1 .toPair) |>.unzip
21
- let width <- xs.toArray.max?.map (· + 1 |>.toNat) |>.getOrThrow "empty input"
22
- let height <- ys.toArray.max?.map (· + 1 |>.toNat) |>.getOrThrow "empty input"
23
- pure { obstacles, start, width, height }
22
+ let width <- xs.max?.map (· + 1 |>.toNat) |>.getOrThrow "empty input"
23
+ let height <- ys.max?.map (· + 1 |>.toNat) |>.getOrThrow "empty input"
24
+ let bounds: Rectangle := { topLeft := Point.origin, width, height }
25
+ pure { obstacles, start, bounds }
24
26
25
- -- #guard parseReports exampleInput == Except.ok 42
27
+ private def examplePuzzleInput := parseInput exampleInput
28
+ #guard (examplePuzzleInput.map (·.bounds)) == Except.ok (Rectangle.mk Point.origin 10 10 )
29
+ #guard (examplePuzzleInput.map (·.start)) == Except.ok ⟨4 , 6 ⟩
30
+ #guard (examplePuzzleInput.map (·.obstacles.size)) == Except.ok 8
0 commit comments