Skip to content

Instantly share code, notes, and snippets.

@Gasoid
Last active January 16, 2022 21:29
Show Gist options
  • Save Gasoid/c871e3c812da679deb8182d0f83f721e to your computer and use it in GitHub Desktop.
Save Gasoid/c871e3c812da679deb8182d0f83f721e to your computer and use it in GitHub Desktop.
package main
func main() {
}
func Merge2Channels(f func(int) int, in1 <-chan int, in2 <-chan int, out chan<- int, n int) {
go func(f func(int) int, in1 <-chan int, in2 <-chan int, out chan<- int) {
done := make(chan bool, n*2)
results := make([]*int, n*2)
go func() {
nDone := 0
for <-done {
for i := nDone; i < n; i++ {
if results[i] != nil && results[i+n] != nil {
out <- (*results[i] + *results[i+n])
if nDone++; nDone == n {
return
}
} else {
break
}
}
}
}()
input := func(ch <-chan int, results []*int) {
for i := 0; i < n; i++ {
x := <-ch
go func(i int, x int) {
result := f(x)
results[i] = &result
done <- true
}(i, x)
}
}
go input(in1, results[:n])
go input(in2, results[n:])
}(f, in1, in2, out)
}
package main
import (
// "fmt"
"log"
"math/rand"
"testing"
"time"
)
func TestMerge2Channels(t *testing.T) {
f := func(n int) int {
sleep := rand.Int31n(10000)
// log.Println("run =", n)
time.Sleep(time.Duration(sleep) * time.Millisecond)
time.Sleep(2 * time.Second)
return (n * n)
}
rand.Seed(12000)
repeats := rand.Intn(400)
in1 := make(chan int, repeats)
in2 := make(chan int, repeats)
out := make(chan int, repeats)
// log.Println("Seed")
log.Println("Merge2Channels")
Merge2Channels(f, in1, in2, out, repeats)
results := []int{}
log.Println("go func")
go func() {
for i := 0; i < repeats; i++ {
i1 := rand.Intn(200)
i2 := rand.Intn(200)
in1 <- i1
in2 <- i2
results = append(results, (i1*i1)+(i2*i2))
}
}()
c := 0
log.Println("range out")
for i := range out {
if i != results[c] {
t.Errorf("%v != %v", i, results[c])
}
log.Println("out =", i)
c++
if c == repeats {
close(out)
}
}
log.Println("cap(in1)", cap(in1))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment