4
4
import Data.Map qualified as M
5
5
import Data.Set qualified as S
6
6
import Data.Maybe (fromJust )
7
+ import Data.Sequence (Seq (.. ), fromList , (><) )
7
8
8
9
main :: IO ()
9
10
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" )
11
15
12
16
type Node = (Int , Int )
13
17
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) }
19
23
enum :: [a ] -> [(Int , a )]
20
24
enum = zip [0 .. ]
21
25
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
24
29
25
30
neighbours :: Grid a -> Node -> [Node ]
26
31
neighbours Grid { items } = filter (`M.member` items) . adjacent
27
32
where adjacent (x, y) = [(x - 1 , y), (x + 1 , y), (x, y - 1 ), (x, y + 1 )]
28
33
29
34
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
31
36
where
32
37
visit x = let item = fromJust $ M. lookup x items in visitor x item
33
38
go [] seen = []
34
39
go (x: xs) seen | S. member x seen = go xs seen
35
40
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