Skip to content

Commit 5fad7d6

Browse files
committed
Add solution for Challenge 4 by yz4230
1 parent 7976a11 commit 5fad7d6

File tree

1 file changed

+111
-0
lines changed

1 file changed

+111
-0
lines changed
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"sync"
6+
)
7+
8+
// ConcurrentBFSQueries concurrently processes BFS queries on the provided graph.
9+
// - graph: adjacency list, e.g., graph[u] = []int{v1, v2, ...}
10+
// - queries: a list of starting nodes for BFS.
11+
// - numWorkers: how many goroutines can process BFS queries simultaneously.
12+
//
13+
// Return a map from the query (starting node) to the BFS order as a slice of nodes.
14+
// YOU MUST use concurrency (goroutines + channels) to pass the performance tests.
15+
func ConcurrentBFSQueries(graph map[int][]int, queries []int, numWorkers int) map[int][]int {
16+
// TODO: Implement concurrency-based BFS for multiple queries.
17+
// Return an empty map so the code compiles but fails tests if unchanged.
18+
19+
if numWorkers <= 0 {
20+
return nil
21+
}
22+
23+
bfs := func(query int) []int {
24+
visited := []int{}
25+
visitedSet := map[int]struct{}{}
26+
queue := []int{}
27+
queue = append(queue, query)
28+
for len(queue) > 0 {
29+
entry := queue[0]
30+
queue = queue[1:]
31+
if _, ok := visitedSet[entry]; ok {
32+
continue
33+
}
34+
visited = append(visited, entry)
35+
visitedSet[entry] = struct{}{}
36+
for _, adj := range graph[entry] {
37+
queue = append(queue, adj)
38+
}
39+
}
40+
41+
return visited
42+
}
43+
44+
type Task struct {
45+
ID int
46+
Key int
47+
}
48+
49+
type Result struct {
50+
ID int
51+
Key int
52+
Visited []int
53+
}
54+
55+
chTask := make(chan Task)
56+
chResult := make(chan Result)
57+
results := map[int][]int{}
58+
59+
wg := &sync.WaitGroup{}
60+
for range numWorkers {
61+
wg.Add(1)
62+
go func() {
63+
defer wg.Done()
64+
for task := range chTask {
65+
chResult <- Result{
66+
ID: task.ID,
67+
Key: task.Key,
68+
Visited: bfs(task.Key),
69+
}
70+
}
71+
}()
72+
}
73+
74+
wg.Add(1)
75+
go func() {
76+
defer wg.Done()
77+
for idx, query := range queries {
78+
chTask <- Task{ID: idx, Key: query}
79+
}
80+
close(chTask)
81+
}()
82+
83+
wg.Add(1)
84+
go func() {
85+
defer wg.Done()
86+
for range len(queries) {
87+
result := <-chResult
88+
results[result.Key] = result.Visited
89+
}
90+
close(chResult)
91+
}()
92+
93+
wg.Wait()
94+
95+
return results
96+
}
97+
98+
func main() {
99+
graph := map[int][]int{
100+
0: {1, 2},
101+
1: {2, 3},
102+
2: {3},
103+
3: {4},
104+
4: {},
105+
}
106+
queries := []int{0, 1, 2}
107+
numWorkers := 2
108+
109+
results := ConcurrentBFSQueries(graph, queries, numWorkers)
110+
fmt.Println(results)
111+
}

0 commit comments

Comments
 (0)