Skip to content

Commit 25ed1af

Browse files
committed
BFS using Data.Sequence for the queue
1 parent 3e5182f commit 25ed1af

File tree

1 file changed

+19
-4
lines changed

1 file changed

+19
-4
lines changed

17.graph.hs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,14 @@
44
import Data.Map qualified as M
55
import Data.Set qualified as S
66
import Data.Maybe (fromJust)
7+
import Data.Sequence (Seq(..), fromList, (><))
78

89
main :: IO ()
910
main = interact $ unlines . demo . parse
10-
where demo grid = dfs grid (0, 0) visitor
11+
where
12+
demo grid = concat [ddfs grid, dbfs grid]
13+
ddfs grid = dfs grid (0, 0) (visitor "dfs")
14+
dbfs grid = bfs grid (0, 0) (visitor "bfs")
1115

1216
type Node = (Int, Int)
1317
data Grid a = Grid { items :: M.Map Node a, maxNode :: Node } deriving Show
@@ -19,17 +23,28 @@ parse s = Grid { items = M.fromList xs, maxNode = fst (last xs) }
1923
enum :: [a] -> [(Int, a)]
2024
enum = zip [0..]
2125

22-
visitor :: (Show a) => (Int, Int) -> a -> String
23-
visitor node item = "visiting item " ++ show item ++ " at " ++ show node
26+
visitor :: (Show a) => String -> (Int, Int) -> a -> String
27+
visitor label node item =
28+
label ++ " visiting item " ++ show item ++ " at " ++ show node
2429

2530
neighbours :: Grid a -> Node -> [Node]
2631
neighbours Grid { items } = filter (`M.member` items) . adjacent
2732
where adjacent (x, y) = [(x - 1, y), (x + 1, y), (x, y - 1), (x, y + 1)]
2833

2934
dfs :: Grid a -> Node -> (Node -> a -> b) -> [b]
30-
dfs grid@Grid { items, maxNode = (mx, my) } start visitor = go [start] S.empty
35+
dfs grid@Grid { items } start visitor = go [start] S.empty
3136
where
3237
visit x = let item = fromJust $ M.lookup x items in visitor x item
3338
go [] seen = []
3439
go (x:xs) seen | S.member x seen = go xs seen
3540
go (x:xs) seen = visit x : go ((neighbours grid x) ++ xs) (S.insert x seen)
41+
42+
-- Data.Sequence provides us with an efficient queue.
43+
bfs :: Grid a -> Node -> (Node -> a -> b) -> [b]
44+
bfs grid@Grid { items } start visitor = go (Empty :|> start) S.empty
45+
where
46+
visit x = let item = fromJust $ M.lookup x items in visitor x item
47+
go Empty seen = []
48+
go (xs :|> x) seen | S.member x seen = go xs seen
49+
go (xs :|> x) seen = visit x : go ys (S.insert x seen)
50+
where ys = (fromList $ neighbours grid x) >< xs

0 commit comments

Comments
 (0)