E. 2 канала

Верно решивших: 62
Рейтинг быстрых решений
Очень похожие решения учитываются в рейтинге один раз.
1 2 3 4 5
Время отправки: 2020-06-02 08:15:25 ID: 360 Время: 0.102s
package main import ( "sync" ) type task struct { f func(int) int in1 <-chan int in2 <-chan int out chan<- int n int } var ( doOnce sync.Once tasks chan task ) // Merge2Channels meges channels func Merge2Channels(f func(int) int, in1 <-chan int, in2 <-chan int, out chan<- int, n int) { type job struct { index int value1 int value2 int } type res struct { index int result int } processor := func(f func(int) int, jobs <-chan job, ress chan<- res) { job := <-jobs f1c := make(chan int) f2c := make(chan int) proc := func(c chan<- int, v int) { c <- f(v) } go proc(f1c, job.value1) go proc(f2c, job.value2) accum := 0 for i := 0; i < 2; i++ { select { case res1 := <-f1c: accum = accum + res1 case res2 := <-f2c: accum = accum + res2 } } ress <- res{ job.index, accum, } } worker := func(taskInput <-chan task) { for { currTask := <-taskInput in1 := currTask.in1 in2 := currTask.in2 f := currTask.f n := currTask.n out := currTask.out jobchan := make(chan job) reschan := make(chan res) for i := 0; i < n; i++ { go processor(f, jobchan, reschan) } for i := 0; i < n; i++ { val1, val2 := <-in1, <-in2 job := job{ i, val1, val2, } jobchan <- job } results := make([]int, n) for i := 0; i < n; i++ { res := <-reschan results[res.index] = res.result } for _, val := range results { out <- val } } } doOnce.Do(func() { tasks = make(chan task) go worker(tasks) }) go func() { tasks <- task{ f, in1, in2, out, n, } }() }
Время отправки: 2020-06-03 07:43:33 ID: 385 Время: 0.102s
package main func main() {} type Terms struct { x int y int order int } func MergeChannels(in1 <-chan int, in2 <-chan int, repeat int) (out chan Terms) { out = make(chan Terms, repeat) readChan := func(in1 <-chan int, in2 <-chan int) { for i := 0; i < repeat; i++ { terms := Terms{x: <-in1, y: <-in2, order: i} out<- terms } } go readChan(in1, in2) return out } func CalcFunction(in chan Terms, f func(int) int) []chan int { repeat := cap(in) var outChans = make([]chan int, repeat) for i := 0; i < repeat; i++ { outChans[i] = make(chan int, 1) } go func() { for ch := range in { go func(terms Terms) { res := f(terms.x) + f(terms.y) outChans[terms.order]<- res }(ch) } }() return outChans } func Merge2Channels(f func(int) int, in1 <-chan int, in2 <-chan int, out chan<- int, n int) { go func() { merged := MergeChannels(in1, in2, n) calc := CalcFunction(merged, f) for i := 0; i < n; i++ { out<- <-calc[i] } }() }
Время отправки: 2020-05-31 16:29:39 ID: 267 Время: 0.103s
package main import "sync" var mutex sync.Mutex func merge(f func(int) int, in1 <-chan int, in2 <-chan int, out chan<- int, n int) { done := make(chan bool, n*2) res := make([]*int, n*2) go pushRes(done, out, n, res) mutex.Lock() go input(f, in1, done, n, res[:n]) go input(f, in2, done, n, res[n:]) } func pushRes(done <-chan bool, out chan<- int, count int, res []*int) { doneCount := 0 for <-done { for i := doneCount; i < count; i++ { if res[i] != nil && res[i+count] != nil { out <- (*res[i] + *res[i+count]) if doneCount++; doneCount == count { mutex.Unlock() return } } else { break } } } } func input(f func(int) int, ch <-chan int, done chan<- bool, count int, res []*int) { for i := 0; i < count; i++ { x := <-ch go func(i int, x int) { result := f(x) res[i] = &result done <- true }(i, x) } } func Merge2Channels(f func(int) int, in1 <-chan int, in2 <-chan int, out chan<- int, n int) { go merge(f, in1, in2, out, n) }
Время отправки: 2020-06-03 15:21:04 ID: 394 Время: 0.103s
package main import "sync" var ( mutex sync.Mutex ) func Merge2Channels(f func(int) int, in1 <-chan int, in2 <-chan int, out chan<- int, n int) { if n <= 0 { return } // Избегаем потенциальных проблем из-за захвата переменных go func(f func(int) int, in1 <-chan int, in2 <-chan int, out chan<- int, n int) { mutex.Lock() const MaxFGoroutinesCount = 100 // Ограничим кол-во горутин // Вычисляем значения f независимо, но возвращаем в том же порядке // Оптимизируем память, избавившить от аллокации O(n) каналов doneCh // В качестве optional int просто используем указатель fs1 := make([]*int, n) // Тут все f(a) fs2 := make([]*int, n) // Тут все f(b) // Сделаем по одному done-каналу на слайс fs1Done := make(chan bool, n) fs2Done := make(chan bool, n) grLimiter := make(chan bool, MaxFGoroutinesCount) // Немного ускорим решение, считывая оба канала полностью независимо, а не попарно readNums := func(k int, in <-chan int, output []*int, doneCh chan<- bool) { for i := 0; i < k; i++ { grLimiter <- true go func(a int, j int) { p := new(int) *p = f(a) output[j] = p doneCh <- true <- grLimiter }(<-in, i) } } go readNums(n, in1, fs1, fs1Done) go readNums(n, in2, fs2, fs2Done) for i := 0; i < n; i++ { for { // Если нужная пара готова - выводим в out и идем дальше if fs1[i] != nil && fs2[i] != nil { out <- *(fs1[i]) + *(fs2[i]) break } // Иначе - ждем, пока что-то еще вычислится, и снова проверим select { case <-fs1Done: case <-fs2Done: } } } mutex.Unlock() }(f, in1, in2, out, n) }
Время отправки: 2020-07-23 14:59:11 ID: 483 Время: 0.103s
package main import "sync" /// plz ... func Merge2Channels(f func(int) int, in1 <-chan int, in2 <- chan int, out chan<- int, n int) { go func() { var wg sync.WaitGroup r := make([]int, n) wg.Add(n) for i := 0; i < n; i++ { x1 := <- in1 x2 := <- in2 go func(idx int) { r[idx] = f(x1) + f(x2) wg.Done() }(i) } wg.Wait() for _, result := range r { out <- result } }() }
Время отправки: 2021-02-27 11:19:41 ID: 521 Время: 0.103s
package main import "sync" func Merge2Channels(f func(int) int, in1 <-chan int, in2 <- chan int, out chan<- int, n int) { order := make([]int, n) var wg sync.WaitGroup go func() { for i := 0; i < n; i++ { wg.Add(1) x1, ok := <-in1 if !ok { break } x2, ok := <-in2 if !ok { break } go func(z int) { k := f(x1) + f(x2) order[z] = k wg.Done() }(i) } wg.Wait() for i := range order { out <- order[i] } }() }
Время отправки: 2020-06-02 07:52:15 ID: 359 Время: 0.124s
package main import ( "sync" ) var mutex = &sync.Mutex{} var anotherMutex = &sync.Mutex{} var readIndex int32 = 0 var writeIndex int32 = 0 type item struct { result int index int32 } type message struct { a, b int index int32 } func Merge2Channels(f func(int) int, in1 <-chan int, in2 <-chan int, out chan<- int, n int) { index := make(map[int32]int, n) opsToIndex := make(chan item, n) readToOps := make(chan message, n) go func() { for i := 0; i < n; i++ { mutex.Lock() x := <-in1 y := <-in2 j := readIndex readIndex++ mutex.Unlock() readToOps <- message{index: j, a: x, b: y} //fmt.Println("Reading of", j, "completed") } }() go func() { for i := 0; i < n; i++ { x := <-readToOps //fmt.Println("Handle", x.index, "item") go func(msg message) { wg := sync.WaitGroup{} var x, y int wg.Add(2) go func() { defer wg.Done() x = f(msg.a) }() go func() { defer wg.Done() y = f(msg.b) }() wg.Wait() opsToIndex <- item{result: x + y, index: msg.index} }(x) } }() go func() { for i := 0; i < n; i++ { x := <-opsToIndex //fmt.Println("Read item", x.index) anotherMutex.Lock() index[x.index] = x.result anotherMutex.Unlock() } }() go func() { for i := 0; i < n; { anotherMutex.Lock() item, ok := index[writeIndex] //fmt.Println("Try extract", writeIndex, ok) if ok { out <- item //fmt.Println("Writing ", item, " to answer") writeIndex++ i++ } anotherMutex.Unlock() } }() }
Время отправки: 2020-05-31 12:05:07 ID: 160 Время: 0.126s
package main import ( "container/list" "sync" "sync/atomic" ) var jobsMutex, nMutex sync.Mutex type Pair struct { x1, x2 int out chan<- int } type Result struct { out chan<- int value int } var jobs = make(chan Pair, 999999) var count int64 func worker(f func(int) int) { jobsMutex.Lock() if atomic.LoadInt64(&count) <= 0 { jobsMutex.Unlock() return } var queue = list.New() loop: for { select { case pair := <-jobs: queue.PushBack(pair) atomic.AddInt64(&count, -1) default: if atomic.LoadInt64(&count) <= 0 { break loop } } } var wait sync.WaitGroup var waitingChans []chan Result for queue.Len() > 0 { e := queue.Front() pair := e.Value.(Pair) waitingChan := make(chan Result, 1) waitingChans = append(waitingChans, waitingChan) wait.Add(1) go func() { result := f(pair.x1) + f(pair.x2) waitingChan <- Result{pair.out, result} }() queue.Remove(e) } for _, waitingChan := range waitingChans { result := <-waitingChan result.out <- result.value wait.Done() } wait.Wait() jobsMutex.Unlock() } func Merge2Channels(f func(int) int, in1 <-chan int, in2 <-chan int, out chan<- int, n int) { atomic.AddInt64(&count, int64(n)) go worker(f) go func() { nMutex.Lock() for i := 0; i < n; i++ { x1, x2 := <-in1, <-in2 pair := Pair{x1, x2, out} jobs <- pair } nMutex.Unlock() }() }
Время отправки: 2020-05-31 12:07:40 ID: 162 Время: 0.133s
package main import ( "time" ) func Merge2Channels(f func(int) int, in1 <-chan int, in2 <-chan int, out chan<- int, n int) { go func() { for i := 0; i < n; i++ { x1 := <-in1 x2 := <-in2 go func(x1 int, x2 int, out chan<- int) { out <- f(x1) + f(x2) }(x1, x2, out) time.Sleep(time.Millisecond) } }() }
Время отправки: 2020-07-25 08:25:42 ID: 485 Время: 0.154s
package main func Merge2Channels(fn func(int) int, in1 <-chan int, in2 <-chan int, out chan<- int, n int) { var a1, a2 int res1 := make([]int, n) res2 := make([]int, n) flag := 0 f := 0 f1 := 0 go func() { i1 := 0 for { select { case a1 = <-in1: i1++ go func(v, k int) { b := fn(v) res1[k-1] = b f++ }(a1, i1) if i1 == n { flag++ return } } } }() go func() { i2 := 0 for { select { case a2 = <-in2: i2++ go func(v, k int) { b := fn(v) res2[k-1] = b f1++ }(a2, i2) if i2 == n { flag++ return } } } }() go func() { for { if f+f1 == 2*n { break } } for j := 0; j < n; j++ { out <- res1[j] + res2[j] } return }() }
1 2 3 4 5