40 lines
1.6 KiB
Haskell
40 lines
1.6 KiB
Haskell
|
import Data.List.Split
|
||
|
import Data.List
|
||
|
import Data.Maybe
|
||
|
|
||
|
getRightMin :: [Integer] -> [Integer] -> Maybe Integer
|
||
|
getRightMin prevRight currRight =
|
||
|
case currRight of
|
||
|
[] -> Nothing
|
||
|
_ -> Just $ minimum $ zipWith (+) prevRight $ tail $ scanl (+) 0 currRight
|
||
|
|
||
|
getLeftMin :: [Integer] -> [Integer] -> Maybe Integer
|
||
|
getLeftMin prevLeft currLeft = getRightMin (reverse prevLeft) (reverse currLeft)
|
||
|
|
||
|
type Acc = ([Integer], [Integer], [Integer], [Integer])
|
||
|
type PrevCurr = (Integer, Integer)
|
||
|
|
||
|
getMin :: Acc -> PrevCurr -> Integer
|
||
|
getMin (prevLeft, currLeft, prevRight, currRight) (prev, curr) =
|
||
|
curr + (minimum $ catMaybes [getLeftMin prevLeft currLeft, Just prev, getRightMin prevRight currRight])
|
||
|
|
||
|
shift :: Acc -> PrevCurr -> Acc
|
||
|
shift (prevLeft, currLeft, prevRight, currRight) (prev, curr) =
|
||
|
(prevLeft ++ [prev], currLeft ++ [curr], tail prevRight, tail currRight)
|
||
|
|
||
|
getNextLine :: [Integer] -> [Integer] -> [Integer]
|
||
|
getNextLine prevLine currLine =
|
||
|
let initPrevLeft = []
|
||
|
initCurrLeft = []
|
||
|
initPrevRight = tail prevLine
|
||
|
initCurrRight = tail currLine
|
||
|
next acc prevCurr = (shift acc prevCurr, getMin acc prevCurr)
|
||
|
in snd $ mapAccumL next (initPrevLeft, initCurrLeft, initPrevRight, initCurrRight) $ zip prevLine currLine
|
||
|
|
||
|
main :: IO ()
|
||
|
main = do
|
||
|
contents <- readFile "p081_matrix.txt"
|
||
|
let fileLines = lines contents
|
||
|
upDownMatrix = map (map read . (splitOn ",")) fileLines
|
||
|
matrix = transpose upDownMatrix
|
||
|
print $ minimum $ foldl getNextLine (head matrix) (tail matrix)
|