Guest User

Untitled

a guest
Dec 15th, 2017
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.36 KB | None | 0 0
  1. {-# LANGUAGE OverloadedStrings #-}
  2. module Main (
  3. main
  4. ) where
  5.  
  6. import Control.Applicative
  7. import Data.Maybe (fromMaybe)
  8. import Data.Foldable
  9. import qualified Data.Map as M
  10. import qualified Data.Set as S
  11. import Data.Text (Text)
  12.  
  13. import qualified Data.Text.IO as TIO
  14. import Data.Attoparsec.Text hiding (parse)
  15.  
  16. type AdjMap a = M.Map a [a]
  17.  
  18. graphNext :: Ord a => AdjMap a -> a -> [a]
  19. graphNext graph x = fromMaybe [] $ M.lookup x graph
  20.  
  21. parse :: Text -> AdjMap Int
  22. parse x =
  23. case parseOnly (M.fromList <$> many (pipe <* endOfLine)) x of
  24. Left _ -> M.empty
  25. Right z -> z
  26. where
  27. pipe :: Parser (Int, [Int])
  28. pipe =
  29. (,) <$> (decimal <* skipSpace) <*>
  30. (string "<->" *> skipSpace *> (decimal `sepBy` (char ',' *> skipSpace)))
  31.  
  32. dfs :: Ord a => (a -> [a]) -> a -> S.Set a
  33. dfs next start = go S.empty [start]
  34. where
  35. go visited [] = visited
  36. go visited (x:xs)
  37. | x `S.member` visited = go visited xs
  38. | otherwise = go (x `S.insert` visited) (next x ++ xs)
  39.  
  40. sccs :: Ord a => AdjMap a -> [S.Set a]
  41. sccs graph
  42. | M.null graph = []
  43. | otherwise =
  44. let start = fst $ M.findMin graph
  45. scc = dfs (graphNext graph) start
  46. in scc : sccs (foldl' (flip M.delete) graph scc)
  47.  
  48. main :: IO ()
  49. main = do
  50. input <- parse <$> TIO.getContents
  51. print . S.size . dfs (graphNext input) $ 0
  52. print . length . sccs $ input
Add Comment
Please, Sign In to add comment