Михаил обнови решението на 09.11.2015 01:42 (преди над 2 години)
+package main
+
+import "fmt"
+
+func SingleLogDrainer(log, input chan string, last, next, closed chan struct{}, number int) {
+ buffer := make([]string, 0)
+ inTurn := false
+ for {
+ msg, ok := <-log
+ if ok {
+ buffer = append(buffer, msg)
+ } else if inTurn {
+ break
+ }
+ select {
+ case <-last:
+ inTurn = true
+ default:
+ }
+ if inTurn {
+ for _, msg := range buffer {
+ input <- fmt.Sprintf("%d\t%s", number, msg)
+ buffer = make([]string, 0, 100)
+ }
+ }
+ }
+ next <- struct{}{}
+ closed <- struct{}{}
+}
+
+func OrderedLogDrainer(logs chan (chan string)) chan string {
+ result := make(chan string)
+ input := make(chan string, 100)
+ syncSender := make(chan struct{})
+
+ go func() {
+ for {
+ select {
+ case <-syncSender:
+ return
+ case msg := <-input:
+ result <- msg
+ }
+ }
+ }()
+
+ go func() {
+ logsCount, closedCount := 0, 0
+ closed := make(chan struct{})
+ next := make(chan struct{}, 1)
+ next <- struct{}{}
+ for {
+ last := next
+ next = make(chan struct{}, 1)
+ if log, ok := <-logs; ok {
+ logsCount += 1
+ go SingleLogDrainer(log, input, last, next, closed, logsCount)
+ } else if closedCount == logsCount && len(input) == 0 {
+ syncSender <- struct{}{}
+ close(result)
+ return
+ }
+ select {
+ case <-closed:
+ closedCount += 1
+ default:
+ }
+ }
+ }()
+
+ return result
+}
за валидно решение на задачата със select
, което все още не сме преподавали. Ако ти се занимава, може да се пробваш да я решиш и само с предадения до момента материал, този път има как :)