@@ -4,75 +4,59 @@ import Data.HashSet (HashSet)
4
4
import qualified Data.HashSet as HashSet
5
5
import Data.Matrix (Matrix , Position )
6
6
import qualified Data.Matrix as M
7
- import Data.Maybe
8
- import Prelude hiding ( Left , Right )
7
+ import Day6.Guard ( Guard ( .. ))
8
+ import qualified Day6.Guard as G
9
9
10
- partOne :: String -> Maybe Int
10
+ data Error = GuardNotFoundError
11
+ deriving (Eq , Show )
12
+
13
+ partOne :: String -> Either Error Int
11
14
partOne input = length <$> predictGuardsRoute (parseLabMap input)
12
15
13
- partTwo :: String -> Int
14
- partTwo _input = 0
16
+ partTwo :: String -> Either Error Int
17
+ partTwo _input = Right 0
15
18
16
19
-- Laboratory Map
17
- --
18
20
type LabMap = Matrix Char
19
21
20
- type Direction = Char
21
-
22
- type Guard = (Position , Direction )
23
-
24
- type Visited = HashSet (Position , Direction )
22
+ type Visited = HashSet Guard
25
23
26
24
parseLabMap :: String -> LabMap
27
25
parseLabMap = M. buildMatrix . lines
28
26
29
- findGuard :: LabMap -> Maybe Guard
27
+ findGuard :: LabMap -> Either Error Guard
30
28
findGuard matrix =
31
29
let mUp = M. lookupValue ' ^' matrix
32
30
mDown = M. lookupValue ' v' matrix
33
31
mRight = M. lookupValue ' >' matrix
34
32
mLeft = M. lookupValue ' <' matrix
35
33
in case [mUp, mDown, mRight, mLeft] of
36
- [Just pos, _, _, _] -> Just ( pos, ' ^ ' )
37
- [_, Just pos, _, _] -> Just ( pos, ' v ' )
38
- [_, _, Just pos, _] -> Just ( pos, ' > ' )
39
- [_, _, _, Just pos] -> Just ( pos, ' < ' )
40
- _ -> Nothing
34
+ [Just pos, _, _, _] -> Right ( Guard pos G. Up )
35
+ [_, Just pos, _, _] -> Right ( Guard pos G. Down )
36
+ [_, _, Just pos, _] -> Right ( Guard pos G. Right )
37
+ [_, _, _, Just pos] -> Right ( Guard pos G. Left )
38
+ _ -> Left GuardNotFoundError
41
39
42
- predictGuardsRoute :: LabMap -> Maybe [Position ]
40
+ predictGuardsRoute :: LabMap -> Either Error [Position ]
43
41
predictGuardsRoute labMap = do
44
42
guard <- findGuard labMap
45
- return ( go guard HashSet. empty HashSet. empty)
43
+ return $ go guard HashSet. empty HashSet. empty
46
44
where
47
45
go :: Guard -> Visited -> HashSet Position -> [Position ]
48
- go guard@ (position, _) visited acc =
46
+ go guard visited acc =
49
47
let guard' = moveGuard guard
50
- acc' = HashSet. insert position acc
48
+ acc' = HashSet. insert ( position guard) acc
51
49
visited' = HashSet. insert guard visited
52
50
in -- If we have hit a loop or if the guard can't move anymore, finish prediction
53
- if HashSet. member guard visited || guard == guard'
51
+ if HashSet. member guard visited || ( guard == guard')
54
52
then HashSet. toList acc'
55
53
else go guard' visited' acc'
56
54
57
55
moveGuard :: Guard -> Guard
58
56
moveGuard guard =
59
- let guard'@ (position', _) = moveForward guard
60
- mObstacle = M. lookup position' labMap
57
+ let guard' = G. moveForward guard
58
+ mObstacle = M. lookup ( position guard') labMap
61
59
in case mObstacle of
62
60
Nothing -> guard
63
- Just ' #' -> turnRight guard
61
+ Just ' #' -> G. turnRight guard
64
62
Just _ -> guard'
65
-
66
- moveForward :: Guard -> Guard
67
- moveForward ((row, col), ' ^' ) = ((row - 1 , col), ' ^' )
68
- moveForward ((row, col), ' v' ) = ((row + 1 , col), ' v' )
69
- moveForward ((row, col), ' >' ) = ((row, col + 1 ), ' >' )
70
- moveForward ((row, col), ' <' ) = ((row, col - 1 ), ' <' )
71
- moveForward guard = guard
72
-
73
- turnRight :: Guard -> Guard
74
- turnRight (pos, ' ^' ) = (pos, ' >' )
75
- turnRight (pos, ' >' ) = (pos, ' v' )
76
- turnRight (pos, ' v' ) = (pos, ' <' )
77
- turnRight (pos, ' <' ) = (pos, ' ^' )
78
- turnRight guard = guard
0 commit comments