2022-12-12 21:40:02 +01:00
import Data.List
import Data.Maybe
type Path = ( [ String ] , [ ( Int , Int ) ] )
main :: IO ()
main = do
2022-12-26 05:46:14 +01:00
input <- lines <$> readFile " input "
2022-12-12 21:40:02 +01:00
let s = findLetter 'S' input
2022-12-26 05:46:14 +01:00
let e = findLetter 'E' input
2022-12-26 06:04:22 +01:00
print $ step 'E' ( input , [] ) [ s ]
print $ step 'a' ( input , [] ) [ e ]
2022-12-12 21:40:02 +01:00
findLetter :: Char -> [ String ] -> ( Int , Int )
findLetter c = f <*> fromJust . findIndex ( /= Nothing ) <$> map ( elemIndex c )
where
f x y = ( head $ catMaybes x , y )
2022-12-26 06:04:22 +01:00
step :: Char -> Path -> [ ( Int , Int ) ] -> Int
2022-12-26 05:46:14 +01:00
step c ( field , visited ) active
2022-12-26 06:04:22 +01:00
| c ` elem ` ( map f active ) = 0
2022-12-26 05:46:14 +01:00
| otherwise = 1 + step c ( field , active ++ visited ) next
2022-12-26 06:04:22 +01:00
where
next = nub $ sort $ concatMap ( nextSteps ( c == 'E' ) ( field , visited ) ) active
f x = field !! snd x !! fst x
2022-12-26 05:46:14 +01:00
2022-12-26 06:04:22 +01:00
nextSteps :: Bool -> Path -> ( Int , Int ) -> [ ( Int , Int ) ]
nextSteps up ( field , visited ) ( x , y ) =
2022-12-26 05:46:14 +01:00
[ ( x + x' , y + y' )
| x' <- [ - 1 .. 1 ]
, x' + x >= 0
, x' + x < lenX
, y' <- [ - 1 .. 1 ]
, y' + y >= 0
, y + y' < lenY
, abs x' /= abs y'
, let a = field !! ( y + y' ) !! ( x + x' )
2022-12-26 06:04:22 +01:00
in ( a ` elem ` reachables || ( a == 'E' && current == 'z' ) )
2022-12-26 05:46:14 +01:00
, ( x + x' , y + y' ) ` notElem ` visited
]
2022-12-12 21:40:02 +01:00
where
lenX = length $ head field
lenY = length field
char = field !! y !! x
2022-12-26 05:46:14 +01:00
current
| char == 'S' = 'a'
| char == 'E' = 'z'
| otherwise = char
2022-12-26 06:04:22 +01:00
reachables =
if up
then [ 'a' .. succ current ]
else [ pred current .. 'z' ]