1
0
Fork 0
projecteuler/83_alt.hs

62 lines
1.9 KiB
Haskell

import Data.List.Split
import Data.Matrix
import Data.Maybe
import Data.Foldable
import Data.PQueue.Min
type Value = Integer
type Distance = Maybe Integer -- Nothing represents infinity
type Position = (Int, Int)
data Element = Element {
value :: Value,
distance :: Distance,
position :: Position
} deriving (Eq, Show)
data PQE = PQE Element Distance deriving (Eq, Show)
instance Ord PQE where
PQE _ Nothing <= _ = False
_ <= PQE _ Nothing = True
PQE _ (Just d1) <= PQE _ (Just d2) = d1 <= d2
dijkstra :: Matrix Element -> MinQueue PQE -> Position -> Distance
dijkstra m q p =
let PQE minElement minDistance = findMin q
in if position minElement == p
then distance minElement
else undefined --TODO
findShortestPathLength :: Matrix Element -> Distance
findShortestPathLength m =
let initialElement = m ! (1, 1)
initialMinQ = singleton $ PQE initialElement $ distance initialElement
lastPos = (nrows m, ncols m)
in dijkstra m initialMinQ lastPos
setInitial :: Matrix Element -> Matrix Element
setInitial m =
let v = value $ m ! (1, 1)
maybeMatrix = safeSet (Element v (Just v) (1, 1)) (1, 1) m
in case maybeMatrix of
Just mm -> mm
Nothing -> m
initElement :: Matrix Integer -> Position -> Element
initElement m p =
let value = m ! p
in Element value Nothing p
toElementMatrix :: Matrix Integer -> Matrix Element
toElementMatrix m =
matrix (nrows m) (ncols m) (initElement m)
main :: IO ()
main = do
contents <- readFile "p083_matrix.txt"
let listsMatrix = fmap (fmap read . (splitOn ",")) $ lines contents :: [[Integer]]
valueMatrix = fromLists listsMatrix
unvisitedMatrix = toElementMatrix valueMatrix
mtrx = setInitial unvisitedMatrix
print $ findShortestPathLength mtrx