mirror of
https://codeberg.org/JasterV/aoc2024-haskell.git
synced 2026-04-27 02:15:43 +00:00
day6 part two
This commit is contained in:
parent
c27e24e063
commit
5bc4508af1
2 changed files with 45 additions and 16 deletions
|
|
@ -11,6 +11,7 @@ module Data.Matrix
|
||||||
lookupMultiple,
|
lookupMultiple,
|
||||||
filterWithKey,
|
filterWithKey,
|
||||||
size,
|
size,
|
||||||
|
insert,
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
|
|
||||||
|
|
@ -50,6 +51,13 @@ lookup position (Matrix hmap) = Map.lookup position hmap
|
||||||
lookupMultiple :: [Position] -> Matrix v -> [v]
|
lookupMultiple :: [Position] -> Matrix v -> [v]
|
||||||
lookupMultiple positions matrix = mapMaybe (`lookup` matrix) positions
|
lookupMultiple positions matrix = mapMaybe (`lookup` matrix) positions
|
||||||
|
|
||||||
|
insert :: Position -> v -> Matrix v -> Matrix v
|
||||||
|
insert position value (Matrix hmap) =
|
||||||
|
Matrix $
|
||||||
|
if Map.member position hmap
|
||||||
|
then Map.insert position value hmap
|
||||||
|
else hmap
|
||||||
|
|
||||||
{--
|
{--
|
||||||
Search for the given value on the matrix.
|
Search for the given value on the matrix.
|
||||||
Return the position of the first match if found and nothing if it doens't exist.
|
Return the position of the first match if found and nothing if it doens't exist.
|
||||||
|
|
|
||||||
53
src/Day6.hs
53
src/Day6.hs
|
|
@ -11,10 +11,24 @@ data Error = GuardNotFoundError
|
||||||
deriving (Eq, Show)
|
deriving (Eq, Show)
|
||||||
|
|
||||||
partOne :: String -> Either Error Int
|
partOne :: String -> Either Error Int
|
||||||
partOne input = length <$> predictGuardsRoute (parseLabMap input)
|
partOne input = do
|
||||||
|
let labMap = parseLabMap input
|
||||||
|
guard <- findGuard labMap
|
||||||
|
let route = predictGuardsRoute guard labMap
|
||||||
|
return (length route)
|
||||||
|
|
||||||
partTwo :: String -> Either Error Int
|
partTwo :: String -> Either Error Int
|
||||||
partTwo _input = Right 0
|
partTwo input = do
|
||||||
|
let labMap = parseLabMap input
|
||||||
|
guard <- findGuard labMap
|
||||||
|
let initialPosition = position guard
|
||||||
|
route = predictGuardsRoute guard labMap
|
||||||
|
candidates = filter (/= initialPosition) route
|
||||||
|
|
||||||
|
return $
|
||||||
|
length $
|
||||||
|
filter (hasLoop guard) $
|
||||||
|
map (\pos -> M.insert pos '#' labMap) candidates
|
||||||
|
|
||||||
-- Laboratory Map
|
-- Laboratory Map
|
||||||
type LabMap = Matrix Char
|
type LabMap = Matrix Char
|
||||||
|
|
@ -37,26 +51,33 @@ findGuard matrix =
|
||||||
[_, _, _, Just pos] -> Right (Guard pos G.Left)
|
[_, _, _, Just pos] -> Right (Guard pos G.Left)
|
||||||
_ -> Left GuardNotFoundError
|
_ -> Left GuardNotFoundError
|
||||||
|
|
||||||
predictGuardsRoute :: LabMap -> Either Error [Position]
|
hasLoop :: Guard -> LabMap -> Bool
|
||||||
predictGuardsRoute labMap = do
|
hasLoop initialGuard labMap = go initialGuard HashSet.empty
|
||||||
guard <- findGuard labMap
|
where
|
||||||
return $ go guard HashSet.empty HashSet.empty
|
go :: Guard -> Visited -> Bool
|
||||||
|
go guard visited =
|
||||||
|
let guard' = moveGuard guard labMap
|
||||||
|
visited' = HashSet.insert guard visited
|
||||||
|
in HashSet.member guard visited || ((guard /= guard') && go guard' visited')
|
||||||
|
|
||||||
|
predictGuardsRoute :: Guard -> LabMap -> [Position]
|
||||||
|
predictGuardsRoute initialGuard labMap = go initialGuard HashSet.empty HashSet.empty
|
||||||
where
|
where
|
||||||
go :: Guard -> Visited -> HashSet Position -> [Position]
|
go :: Guard -> Visited -> HashSet Position -> [Position]
|
||||||
go guard visited acc =
|
go guard visited acc =
|
||||||
let guard' = moveGuard guard
|
let guard' = moveGuard guard labMap
|
||||||
acc' = HashSet.insert (position guard) acc
|
acc' = HashSet.insert (position guard) acc
|
||||||
visited' = HashSet.insert guard visited
|
visited' = HashSet.insert guard visited
|
||||||
in -- If we have hit a loop or if the guard can't move anymore, finish prediction
|
in -- If we have hit a loop or if the guard can't move anymore, finish prediction
|
||||||
if HashSet.member guard visited || (guard == guard')
|
if HashSet.member guard visited || guard == guard'
|
||||||
then HashSet.toList acc'
|
then HashSet.toList acc'
|
||||||
else go guard' visited' acc'
|
else go guard' visited' acc'
|
||||||
|
|
||||||
moveGuard :: Guard -> Guard
|
moveGuard :: Guard -> LabMap -> Guard
|
||||||
moveGuard guard =
|
moveGuard guard labMap =
|
||||||
let guard' = G.moveForward guard
|
let guard' = G.moveForward guard
|
||||||
mObstacle = M.lookup (position guard') labMap
|
mObstacle = M.lookup (position guard') labMap
|
||||||
in case mObstacle of
|
in case mObstacle of
|
||||||
Nothing -> guard
|
Nothing -> guard
|
||||||
Just '#' -> G.turnRight guard
|
Just '#' -> G.turnRight guard
|
||||||
Just _ -> guard'
|
Just _ -> guard'
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue