mirror of
https://github.com/blindlobstar/go-interview-problems
synced 2025-04-19 16:25:15 +00:00
merge channels problem
This commit is contained in:
parent
a22a1968be
commit
9146c23ff9
13
09-merge-channels/README.md
Normal file
13
09-merge-channels/README.md
Normal file
@ -0,0 +1,13 @@
|
||||
# Merge Channels
|
||||
Implement the `Merge` function that takes a variable number of input channels and returns a single output channel. The output channel should receive all values from all input channels. Once all input channels are closed and all values have been sent to the output channel, the output channel should be closed.
|
||||
|
||||
Requirements:
|
||||
|
||||
1. The function should handle any number of input channels, including zero.
|
||||
2. All values from all input channels must be sent to the output channel.
|
||||
3. The output channel should be closed only after all input channels are closed and all values have been forwarded.
|
||||
4. Your implementation must not leak goroutines.
|
||||
5. Values should be forwarded as soon as they are available from any input channel.
|
||||
|
||||
## Tags
|
||||
`Concurrency`
|
24
09-merge-channels/solution/solution.go
Normal file
24
09-merge-channels/solution/solution.go
Normal file
@ -0,0 +1,24 @@
|
||||
package main
|
||||
|
||||
import "sync"
|
||||
|
||||
func Merge(channels ...<-chan int) <-chan int {
|
||||
out := make(chan int)
|
||||
var wg sync.WaitGroup
|
||||
for _, in := range channels {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
for val := range in {
|
||||
out <- val
|
||||
}
|
||||
wg.Done()
|
||||
}()
|
||||
}
|
||||
|
||||
go func() {
|
||||
wg.Wait()
|
||||
close(out)
|
||||
}()
|
||||
|
||||
return out
|
||||
}
|
5
09-merge-channels/task.go
Normal file
5
09-merge-channels/task.go
Normal file
@ -0,0 +1,5 @@
|
||||
package main
|
||||
|
||||
func Merge(channels ...<-chan int) <-chan int {
|
||||
return nil
|
||||
}
|
75
09-merge-channels/task_test.go
Normal file
75
09-merge-channels/task_test.go
Normal file
@ -0,0 +1,75 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"sort"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMerge(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
values [][]int
|
||||
result []int
|
||||
}{
|
||||
{
|
||||
name: "empty input",
|
||||
values: [][]int{},
|
||||
result: []int{},
|
||||
},
|
||||
{
|
||||
name: "single empty channel",
|
||||
values: [][]int{{}},
|
||||
result: []int{},
|
||||
},
|
||||
{
|
||||
name: "single channel with values",
|
||||
values: [][]int{{3, 1, 4}},
|
||||
result: []int{1, 3, 4},
|
||||
},
|
||||
{
|
||||
name: "multiple channels with balanced load",
|
||||
values: [][]int{{9, 3}, {8, 2}, {7, 1}},
|
||||
result: []int{1, 2, 3, 7, 8, 9},
|
||||
},
|
||||
{
|
||||
name: "channels with uneven distributions",
|
||||
values: [][]int{{5}, {}, {1, 2, 3, 4}},
|
||||
result: []int{1, 2, 3, 4, 5},
|
||||
},
|
||||
{
|
||||
name: "channels with duplicate values",
|
||||
values: [][]int{{1, 3}, {1, 3}, {3}},
|
||||
result: []int{1, 1, 3, 3, 3},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
channels := []<-chan int{}
|
||||
for _, chValues := range tt.values {
|
||||
ch := make(chan int)
|
||||
channels = append(channels, ch)
|
||||
go func() {
|
||||
for _, val := range chValues {
|
||||
ch <- val
|
||||
}
|
||||
close(ch)
|
||||
}()
|
||||
}
|
||||
out := Merge(channels...)
|
||||
|
||||
result := []int{}
|
||||
for val := range out {
|
||||
result = append(result, val)
|
||||
}
|
||||
|
||||
sort.Ints(tt.result)
|
||||
sort.Ints(result)
|
||||
|
||||
if !reflect.DeepEqual(tt.result, result) {
|
||||
t.Errorf("Expected: %+q, got: %+q", tt.result, result)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user