merge channels problem

This commit is contained in:
blindlobstar 2025-04-07 15:03:42 +02:00
parent a22a1968be
commit 9146c23ff9
5 changed files with 118 additions and 0 deletions

View 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`

View 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
}

View File

@ -0,0 +1,5 @@
package main
func Merge(channels ...<-chan int) <-chan int {
return nil
}

View 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)
}
})
}
}

View File

@ -26,6 +26,7 @@ Here is a list of the problems available in the repository. Problems are organiz
* [Rate Limiter](06-rate-limiter/)
* [TTL Cache](07-ttl-cache/)
* [Request With Failover](08-request-with-failover/)
* [Merge Channels](09-merge-channels/)
## Contributing