35 lines
1.4 KiB
Haskell
35 lines
1.4 KiB
Haskell
|
import Data.List (elemIndex)
|
||
|
import Data.Matrix (Matrix, fromLists, (!))
|
||
|
|
||
|
type Grid = Matrix Char
|
||
|
data Direction = North | South | West | East | Stop deriving Eq
|
||
|
data State = State (Int, Int) Direction [Char] Int
|
||
|
|
||
|
nextState :: String -> Grid -> State -> State
|
||
|
nextState letters grid (State (r, c) dir seen count) =
|
||
|
let (nextR, nextC) = case dir of
|
||
|
North -> (r - 1, c)
|
||
|
South -> (r + 1, c)
|
||
|
West -> (r, c - 1)
|
||
|
East -> (r, c + 1)
|
||
|
nextChar = grid ! (nextR, nextC)
|
||
|
nextDir = case nextChar of
|
||
|
'+' -> if dir `elem` [North, South]
|
||
|
then if grid ! (nextR, nextC - 1) == '-' then West else East
|
||
|
else if grid ! (nextR - 1, nextC) == '|' then North else South
|
||
|
' ' -> Stop
|
||
|
_ -> dir
|
||
|
nextSeen = if nextChar `elem` letters then nextChar : seen else seen
|
||
|
in State (nextR, nextC) nextDir nextSeen (count + 1)
|
||
|
|
||
|
traverseGrid :: String -> Grid -> State -> (String, Int)
|
||
|
traverseGrid _ _ (State _ Stop seen count) = (reverse seen, count)
|
||
|
traverseGrid letters grid state = traverseGrid letters grid $ nextState letters grid state
|
||
|
|
||
|
main :: IO ()
|
||
|
main = do
|
||
|
input <- readFile "19.txt"
|
||
|
let rows = lines input
|
||
|
Just start = (+1) <$> (elemIndex '|' $ head rows)
|
||
|
letters = filter (not . (`elem` " +|-\n")) input
|
||
|
print $ traverseGrid letters (fromLists rows) (State (1, start) South [] 0)
|