Skip to content

Instantly share code, notes, and snippets.

@nsmaciej
Created January 22, 2014 18:56
Show Gist options
  • Save nsmaciej/8564984 to your computer and use it in GitHub Desktop.
Save nsmaciej/8564984 to your computer and use it in GitHub Desktop.
Dijkstra algorithm in Haskell.
import System.Environment
import Control.Applicative
check :: Int
check = -1
type Nodeid = Int
type Node = Int
type Graph = [(Node, [Edge])]
data Edge = Edge { enid :: Nodeid
, eprice :: Int } deriving (Show)
map2 :: (a -> a -> b) -> [a] -> [b]
map2 f [] = []
map2 f (a:b:as) = f a b:map2 f as
setNodeValue :: Nodeid -> Int -> Graph -> Graph
setNodeValue i n g = fp ++ nv:sp
where nv = (n, getEdgeList i g) --New value
fp = take i g --Left
sp = drop (i+1) g --Right
getNodeValue :: Nodeid -> Graph -> Int
getNodeValue n g = fst $ g !! n
getEdgeList :: Nodeid -> Graph -> [Edge]
getEdgeList n g = snd $ g !! n
findUnchechNodes :: Nodeid -> Graph -> [Nodeid]
findUnchechNodes a g = filter (\x -> check == getNodeValue x g) enids
where enids = map enid $ getEdgeList a g
relaxNodes :: Nodeid -> Graph -> Graph
relaxNodes a g =
foldr (\edge acc ->
let nprice = (getNodeValue a g) + eprice edge
onid = enid edge
nodeval = getNodeValue onid g
in if nodeval == check || nodeval > nprice
then setNodeValue onid nprice acc
else acc
) g $ getEdgeList a g
solve :: Bool -> Nodeid -> Graph -> Graph
solve ft a g = if length rg == 0
then rg
else foldr (solve False) rg ucn
where ucn = findUnchechNodes a sg
rg = relaxNodes a sg
sg = if ft
then setNodeValue a 0 g
else g
main :: IO ()
main = do
start <- read . head <$> getArgs
pgraph <- map (map read . words) . lines <$> getContents
printGraph . solve True start $ map readAList pgraph
where readAList es = (check, map2 Edge es)
printGraph = mapM_ (print . fst)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment