topkata-0.2.3: Dijkstra.hs
module Dijkstra
(dijkstra)
where
import Data.Ix
import Data.Array
import Data.Maybe
import Data.List
{-
class RasterWorld rw where
neighbors :: Ix a => rw -> a -> [a]
rwbounds :: Ix a => rw -> (a, a)
-}
-- dijkstra :: (Ix a, RasterWorld rw) => rw -> a -> Array a Int
dijkstra rw pos bnds neighbors =
dijkstraUpdate rw (initArray // [(pos, 0)]) (neighbors rw pos) neighbors
where
rng = range bnds
initArray = array bnds [ (ix, maxBound :: Int) | ix <- rng ]
-- dijkstraUpdate :: (Ix a, RasterWorld rw) => rw -> Array a Int -> [a] -> Array a Int
dijkstraUpdate rw a todo neighbors =
if null todo' then a' else dijkstraUpdate rw a' (nub todo') neighbors
where
(update, todo') = foldl updateOne ([], []) todo
a' = a // update
updateOne acc@(u, td) ix =
let nbDist = 1+(minimum $ map (a !) nb)
nb = neighbors rw ix
in
if nbDist < a ! ix then ((ix, nbDist):u, nb ++ td)
else acc