Skip to content

Commit 5bc4508

Browse files
committed
day6 part two
1 parent c27e24e commit 5bc4508

File tree

2 files changed

+45
-16
lines changed

2 files changed

+45
-16
lines changed

src/Data/Matrix.hs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ module Data.Matrix
1111
lookupMultiple,
1212
filterWithKey,
1313
size,
14+
insert,
1415
)
1516
where
1617

@@ -50,6 +51,13 @@ lookup position (Matrix hmap) = Map.lookup position hmap
5051
lookupMultiple :: [Position] -> Matrix v -> [v]
5152
lookupMultiple positions matrix = mapMaybe (`lookup` matrix) positions
5253

54+
insert :: Position -> v -> Matrix v -> Matrix v
55+
insert position value (Matrix hmap) =
56+
Matrix $
57+
if Map.member position hmap
58+
then Map.insert position value hmap
59+
else hmap
60+
5361
{--
5462
Search for the given value on the matrix.
5563
Return the position of the first match if found and nothing if it doens't exist.

src/Day6.hs

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,24 @@ data Error = GuardNotFoundError
1111
deriving (Eq, Show)
1212

1313
partOne :: String -> Either Error Int
14-
partOne input = length <$> predictGuardsRoute (parseLabMap input)
14+
partOne input = do
15+
let labMap = parseLabMap input
16+
guard <- findGuard labMap
17+
let route = predictGuardsRoute guard labMap
18+
return (length route)
1519

1620
partTwo :: String -> Either Error Int
17-
partTwo _input = Right 0
21+
partTwo input = do
22+
let labMap = parseLabMap input
23+
guard <- findGuard labMap
24+
let initialPosition = position guard
25+
route = predictGuardsRoute guard labMap
26+
candidates = filter (/= initialPosition) route
27+
28+
return $
29+
length $
30+
filter (hasLoop guard) $
31+
map (\pos -> M.insert pos '#' labMap) candidates
1832

1933
-- Laboratory Map
2034
type LabMap = Matrix Char
@@ -37,26 +51,33 @@ findGuard matrix =
3751
[_, _, _, Just pos] -> Right (Guard pos G.Left)
3852
_ -> Left GuardNotFoundError
3953

40-
predictGuardsRoute :: LabMap -> Either Error [Position]
41-
predictGuardsRoute labMap = do
42-
guard <- findGuard labMap
43-
return $ go guard HashSet.empty HashSet.empty
54+
hasLoop :: Guard -> LabMap -> Bool
55+
hasLoop initialGuard labMap = go initialGuard HashSet.empty
56+
where
57+
go :: Guard -> Visited -> Bool
58+
go guard visited =
59+
let guard' = moveGuard guard labMap
60+
visited' = HashSet.insert guard visited
61+
in HashSet.member guard visited || ((guard /= guard') && go guard' visited')
62+
63+
predictGuardsRoute :: Guard -> LabMap -> [Position]
64+
predictGuardsRoute initialGuard labMap = go initialGuard HashSet.empty HashSet.empty
4465
where
4566
go :: Guard -> Visited -> HashSet Position -> [Position]
4667
go guard visited acc =
47-
let guard' = moveGuard guard
68+
let guard' = moveGuard guard labMap
4869
acc' = HashSet.insert (position guard) acc
4970
visited' = HashSet.insert guard visited
5071
in -- If we have hit a loop or if the guard can't move anymore, finish prediction
51-
if HashSet.member guard visited || (guard == guard')
72+
if HashSet.member guard visited || guard == guard'
5273
then HashSet.toList acc'
5374
else go guard' visited' acc'
5475

55-
moveGuard :: Guard -> Guard
56-
moveGuard guard =
57-
let guard' = G.moveForward guard
58-
mObstacle = M.lookup (position guard') labMap
59-
in case mObstacle of
60-
Nothing -> guard
61-
Just '#' -> G.turnRight guard
62-
Just _ -> guard'
76+
moveGuard :: Guard -> LabMap -> Guard
77+
moveGuard guard labMap =
78+
let guard' = G.moveForward guard
79+
mObstacle = M.lookup (position guard') labMap
80+
in case mObstacle of
81+
Nothing -> guard
82+
Just '#' -> G.turnRight guard
83+
Just _ -> guard'

0 commit comments

Comments
 (0)