import Data.List import Data.Maybe type Path = ([String], [(Int, Int)]) main :: IO () main = do input <- lines <$> readFile "testinput" let s = findLetter 'S' input print $ walkTo 'E' (input, []) s findLetter :: Char -> [String] -> (Int, Int) findLetter c = f <*> fromJust . findIndex (/= Nothing) <$> map (elemIndex c) where f x y = (head $ catMaybes x, y) walkTo :: Char -> Path -> (Int, Int) -> Int walkTo c (field, visited) (x, y) | field !! y !! x == c = 0 | null newCoords = (maxBound :: Int) `div` 2 | otherwise = if length visited > lenX * lenY then (maxBound :: Int) `div` 2 else succ $ minimum $ map (walkTo c (field, (x, y) : visited)) newCoords where lenX = length $ head field lenY = length field char = field !! y !! x current = if char == 'S' then pred 'a' else char newCoords = [ (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') in (a `elem` ['a' .. succ current] || (a == 'E' && current == 'z')) , (x + x', y + y') `notElem` visited ]