From 8ac2ad26bb8920ad2698cf0d6e86aa5a04dd7391 Mon Sep 17 00:00:00 2001 From: Gattix Date: Mon, 26 Dec 2022 05:46:14 +0100 Subject: [PATCH] day 12: solution that actually works --- 2022/day12/day12.hs | 56 ++++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 29 deletions(-) diff --git a/2022/day12/day12.hs b/2022/day12/day12.hs index 579986f..6ef3bcb 100644 --- a/2022/day12/day12.hs +++ b/2022/day12/day12.hs @@ -5,43 +5,41 @@ type Path = ([String], [(Int, Int)]) main :: IO () main = do - input <- lines <$> readFile "testinput" + input <- lines <$> readFile "input" let s = findLetter 'S' input - print $ walkTo 'E' (input, []) s + let e = findLetter 'E' input + print $ step 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 +step :: (Int,Int)->Path -> [(Int, Int)] -> Int +step c (field, visited) active + | c `elem` active = 0 + | otherwise = 1 + step c (field, active ++ visited) next + where next = nub $ sort $ concatMap (nextSteps (field, visited)) active + +nextSteps :: Path -> (Int, Int) -> [(Int, Int)] +nextSteps (field, visited) (x, y) = + [ (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 + ] 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 - ] + current + | char == 'S' = 'a' + | char == 'E' = 'z' + | otherwise = char