Problem 83: technically correct solution, but very slow...
This commit is contained in:
parent
3a3dcc70eb
commit
5a49c8845f
43
83.hs
43
83.hs
|
@ -9,14 +9,15 @@ type Position = (Int, Int)
|
||||||
data Element = Element Value IsVisited Position deriving (Eq, Show)
|
data Element = Element Value IsVisited Position deriving (Eq, Show)
|
||||||
|
|
||||||
instance Monoid Element where
|
instance Monoid Element where
|
||||||
mempty = Element 0 Visited (0, 0)
|
mempty = Element 0 Unvisited (0, 0)
|
||||||
e `mappend` Element _ Unvisited _ = e
|
e `mappend` Element _ Unvisited _ = e
|
||||||
Element _ Unvisited _ `mappend` e = e
|
Element _ Unvisited _ `mappend` e = e
|
||||||
Element v1 Visited p1 `mappend` Element v2 Visited p2 =
|
Element v1 Visited p1 `mappend` Element v2 Visited p2 =
|
||||||
case getMin v1 v2 of
|
case getMin v1 v2 of
|
||||||
0 -> mempty
|
0 -> mempty
|
||||||
v1 -> Element v1 Visited p1
|
v -> if v == v1
|
||||||
v2 -> Element v2 Visited p2
|
then Element v1 Visited p1
|
||||||
|
else Element v2 Visited p2
|
||||||
|
|
||||||
getMin :: Value -> Value -> Value
|
getMin :: Value -> Value -> Value
|
||||||
getMin v1 0 = v1
|
getMin v1 0 = v1
|
||||||
|
@ -25,11 +26,11 @@ getMin v1 v2 = min v1 v2
|
||||||
|
|
||||||
getUnvisitedNeighbours :: Matrix Element -> Element -> [Element]
|
getUnvisitedNeighbours :: Matrix Element -> Element -> [Element]
|
||||||
getUnvisitedNeighbours m (Element _ _ (i, j)) =
|
getUnvisitedNeighbours m (Element _ _ (i, j)) =
|
||||||
filter (\(Element _ isVisited _) -> isVisited == Visited)
|
filter (\(Element _ isVisited _) -> isVisited == Unvisited)
|
||||||
(catMaybes [safeGet (i - 1) j m
|
(catMaybes [safeGet (i - 1) j m,
|
||||||
,safeGet (i + 1) j m
|
safeGet (i + 1) j m,
|
||||||
,safeGet i (j - 1) m
|
safeGet i (j - 1) m,
|
||||||
,safeGet i (j + 1) m])
|
safeGet i (j + 1) m])
|
||||||
|
|
||||||
getNeighbourDistances :: Element -> [Element] -> [Element]
|
getNeighbourDistances :: Element -> [Element] -> [Element]
|
||||||
getNeighbourDistances e = map (addValue e)
|
getNeighbourDistances e = map (addValue e)
|
||||||
|
@ -39,10 +40,6 @@ dijkstraMatrix :: Matrix Element -> Element
|
||||||
dijkstraMatrix m =
|
dijkstraMatrix m =
|
||||||
let neighbourDistanceMatrix = fmap (\e -> getNeighbourDistances e (getUnvisitedNeighbours m e)) m
|
let neighbourDistanceMatrix = fmap (\e -> getNeighbourDistances e (getUnvisitedNeighbours m e)) m
|
||||||
in fold (fmap fold neighbourDistanceMatrix)
|
in fold (fmap fold neighbourDistanceMatrix)
|
||||||
-- for unvisited element in matrix
|
|
||||||
-- for unvisited neighbour of element
|
|
||||||
-- if element value + neighbour value < min then set as min
|
|
||||||
-- return min; default is (0, (0, 0))
|
|
||||||
|
|
||||||
nextMatrix :: Matrix Element -> Matrix Element
|
nextMatrix :: Matrix Element -> Matrix Element
|
||||||
nextMatrix m =
|
nextMatrix m =
|
||||||
|
@ -52,6 +49,14 @@ nextMatrix m =
|
||||||
Just next -> next
|
Just next -> next
|
||||||
Nothing -> m
|
Nothing -> m
|
||||||
|
|
||||||
|
setInitial :: Matrix Element -> Matrix Element
|
||||||
|
setInitial m =
|
||||||
|
let Element v _ _ = m ! (1, 1)
|
||||||
|
maybeMatrix = safeSet (Element v Visited (1, 1)) (1, 1) m
|
||||||
|
in case maybeMatrix of
|
||||||
|
Just mm -> mm
|
||||||
|
Nothing -> m
|
||||||
|
|
||||||
initElement :: Matrix Integer -> Position -> Element
|
initElement :: Matrix Integer -> Position -> Element
|
||||||
initElement m p =
|
initElement m p =
|
||||||
let value = m ! p
|
let value = m ! p
|
||||||
|
@ -61,10 +66,18 @@ toElementMatrix :: Matrix Integer -> Matrix Element
|
||||||
toElementMatrix m =
|
toElementMatrix m =
|
||||||
matrix (nrows m) (ncols m) (initElement m)
|
matrix (nrows m) (ncols m) (initElement m)
|
||||||
|
|
||||||
|
findShortestPathLength :: Matrix Element -> Value
|
||||||
|
findShortestPathLength m =
|
||||||
|
let Element v isVisited _ = m ! (nrows m, ncols m)
|
||||||
|
in case isVisited of
|
||||||
|
Visited -> v
|
||||||
|
Unvisited -> findShortestPathLength $ nextMatrix m
|
||||||
|
|
||||||
main :: IO ()
|
main :: IO ()
|
||||||
main = do
|
main = do
|
||||||
contents <- readFile "p081_matrix.txt"
|
contents <- readFile "p083_matrix.txt"
|
||||||
let listsMatrix = map (map read . (splitOn ",")) $ lines contents :: [[Integer]]
|
let listsMatrix = map (map read . (splitOn ",")) $ lines contents :: [[Integer]]
|
||||||
valueMatrix = fromLists listsMatrix
|
valueMatrix = fromLists listsMatrix
|
||||||
mtrx = toElementMatrix valueMatrix
|
unvisitedMatrix = toElementMatrix valueMatrix
|
||||||
print $ nextMatrix mtrx
|
mtrx = setInitial unvisitedMatrix
|
||||||
|
print $ findShortestPathLength mtrx
|
|
@ -0,0 +1,5 @@
|
||||||
|
131,673,234,103,18
|
||||||
|
201,96,342,965,150
|
||||||
|
630,803,746,422,111
|
||||||
|
537,699,497,121,956
|
||||||
|
805,732,524,37,331
|
Loading…
Reference in New Issue