diff --git a/2022/day12/day12.hs b/2022/day12/day12.hs new file mode 100644 index 0000000..579986f --- /dev/null +++ b/2022/day12/day12.hs @@ -0,0 +1,47 @@ +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 + ]