Решение на Concurrent Tasks от Александър Йорданов

Обратно към всички решения

Към профила на Александър Йорданов

Резултати

  • 0 точки от тестове
  • 0 бонус точки
  • 0 точки общо
  • 0 успешни тест(а)
  • 13 неуспешни тест(а)

Код

package main
import (
"errors"
"fmt"
"sync"
"time"
)
// ############ TASK 1 #############
type Task interface {
Execute(int) (int, error)
}
type adder struct {
augend int
}
type executor struct {
tasks []Task
}
func (ex executor) Execute(number int) (int, error) {
var result int
var err error
if len(ex.tasks) == 0 {
return 0, errors.New("some err")
}
for i, task := range ex.tasks {
if i == 0 {
result, err = task.Execute(number)
} else {
result, err = task.Execute(result)
}
if err != nil {
return 0, errors.New("some err")
}
}
return result, nil
}
func (a adder) Execute(addend int) (int, error) {
result := a.augend + addend
if result > 127 {
return 0, fmt.Errorf("Result %d exceeds the adder threshold", a)
}
return result, nil
}
func Pipeline(tasks ...Task) Task {
return &executor{tasks}
}
// ############ TASK 2 #############
type lazyAdder struct {
adder
delay time.Duration
}
type executor2 struct {
tasks []Task
}
func (ex executor2) Execute(number int) (int, error) {
if len(ex.tasks) == 0 {
return 0, errors.New("some err")
}
c := make(chan int, len(ex.tasks))
for _, task := range ex.tasks {
go func() {
res, _ := task.Execute(number)
c <- res
}()
}
return <-c, nil
}
func (la lazyAdder) Execute(addend int) (int, error) {
time.Sleep(la.delay * time.Millisecond)
return la.adder.Execute(addend)
}
func Fastest(tasks ...Task) Task {
return &executor2{tasks}
}
// ############ TASK 3 #############
type executor3 struct {
task Task
timeout time.Duration
}
func (ex executor3) Execute(number int) (int, error) {
type result struct {
res int
err error
}
c := make(chan result, 1)
go func() {
res, err := ex.task.Execute(number)
c <- result{res, err}
}()
select {
case res := <-c:
if res.err != nil {
return res.res, nil
}
return 0, res.err
case <-time.After(ex.timeout):
return 0, errors.New("some timeout err")
}
return 0, nil
}
func Timed(task Task, timeout time.Duration) Task {
return &executor3{task, timeout}
}
// ############ TASK 4 #############
type executor4 struct {
tasks []Task
f func([]int) int
}
func (ex executor4) Execute(number int) (int, error) {
if len(ex.tasks) == 0 {
return 0, errors.New("some err")
}
type result struct {
res int
err error
}
c := make(chan result, len(ex.tasks))
var wg sync.WaitGroup
wg.Add(len(ex.tasks))
for _, task := range ex.tasks {
go func() {
res, err := task.Execute(number)
c <- result{res, err}
wg.Done()
}()
}
wg.Wait()
close(c)
results := make([]int, 0)
for res := range c {
results = append(results, res.res)
if res.err != nil {
return 0, errors.New("big error here")
}
}
return ex.f(results), nil
}
func ConcurrentMapReduce(reduce func(results []int) int, tasks ...Task) Task {
return &executor4{tasks, reduce}
}
// ############ TASK 5 #############
// NOT DONE
type executor5 struct {
}
func (ex executor5) Execute(number int) (int, error) {
return 0, nil
}
func GreatestSearcher(errorLimit int, tasks <-chan Task) Task {
return &executor5{}
}
func main() {
if res, err := Pipeline(adder{50}, adder{60}).Execute(10); err != nil {
fmt.Printf("The pipeline returned an error\n")
} else {
fmt.Printf("The pipeline returned %d\n", res)
}
f := Fastest(
lazyAdder{adder{20}, 500},
lazyAdder{adder{50}, 300},
adder{41},
)
res, err := f.Execute(1)
fmt.Println(res, err)
_, e1 := Timed(lazyAdder{adder{20}, 50}, 2*time.Millisecond).Execute(2)
r2, e2 := Timed(lazyAdder{adder{20}, 50}, 300*time.Millisecond).Execute(2)
fmt.Println(e1)
fmt.Println(r2, e2)
reduce := func(results []int) int {
smallest := 128
for _, v := range results {
if v < smallest {
smallest = v
}
}
return smallest
}
mr := ConcurrentMapReduce(reduce, adder{30}, adder{50}, adder{20})
if res, err := mr.Execute(5); err != nil {
fmt.Printf("We got an error!\n")
} else {
fmt.Printf("The ConcurrentMapReduce returned %d\n", res)
}
tasks := make(chan Task)
gs := GreatestSearcher(2, tasks)
go func() {
tasks <- adder{4}
tasks <- lazyAdder{adder{22}, 20}
tasks <- adder{125}
time.Sleep(50 * time.Millisecond)
tasks <- adder{32}
tasks <- Timed(lazyAdder{adder{100}, 2000}, 20*time.Millisecond)
close(tasks)
}()
result, err := gs.Execute(10)
fmt.Println(result)
}

Лог от изпълнението

# _/tmp/d20161129-30451-3w4d6r
./solution_test.go:15: adder redeclared in this block
	previous declaration at ./solution.go:15
./solution_test.go:19: adder.Execute redeclared in this block
	previous declaration at ./solution.go:40
./solution_test.go:27: lazyAdder redeclared in this block
	previous declaration at ./solution.go:52
./solution_test.go:32: lazyAdder.Execute redeclared in this block
	previous declaration at ./solution.go:74
FAIL	_/tmp/d20161129-30451-3w4d6r [build failed]
# _/tmp/d20161129-30451-3w4d6r
./solution_test.go:15: adder redeclared in this block
	previous declaration at ./solution.go:15
./solution_test.go:19: adder.Execute redeclared in this block
	previous declaration at ./solution.go:40
./solution_test.go:27: lazyAdder redeclared in this block
	previous declaration at ./solution.go:52
./solution_test.go:32: lazyAdder.Execute redeclared in this block
	previous declaration at ./solution.go:74
FAIL	_/tmp/d20161129-30451-3w4d6r [build failed]
# _/tmp/d20161129-30451-3w4d6r
./solution_test.go:15: adder redeclared in this block
	previous declaration at ./solution.go:15
./solution_test.go:19: adder.Execute redeclared in this block
	previous declaration at ./solution.go:40
./solution_test.go:27: lazyAdder redeclared in this block
	previous declaration at ./solution.go:52
./solution_test.go:32: lazyAdder.Execute redeclared in this block
	previous declaration at ./solution.go:74
FAIL	_/tmp/d20161129-30451-3w4d6r [build failed]
# _/tmp/d20161129-30451-3w4d6r
./solution_test.go:15: adder redeclared in this block
	previous declaration at ./solution.go:15
./solution_test.go:19: adder.Execute redeclared in this block
	previous declaration at ./solution.go:40
./solution_test.go:27: lazyAdder redeclared in this block
	previous declaration at ./solution.go:52
./solution_test.go:32: lazyAdder.Execute redeclared in this block
	previous declaration at ./solution.go:74
FAIL	_/tmp/d20161129-30451-3w4d6r [build failed]
# _/tmp/d20161129-30451-3w4d6r
./solution_test.go:15: adder redeclared in this block
	previous declaration at ./solution.go:15
./solution_test.go:19: adder.Execute redeclared in this block
	previous declaration at ./solution.go:40
./solution_test.go:27: lazyAdder redeclared in this block
	previous declaration at ./solution.go:52
./solution_test.go:32: lazyAdder.Execute redeclared in this block
	previous declaration at ./solution.go:74
FAIL	_/tmp/d20161129-30451-3w4d6r [build failed]
# _/tmp/d20161129-30451-3w4d6r
./solution_test.go:15: adder redeclared in this block
	previous declaration at ./solution.go:15
./solution_test.go:19: adder.Execute redeclared in this block
	previous declaration at ./solution.go:40
./solution_test.go:27: lazyAdder redeclared in this block
	previous declaration at ./solution.go:52
./solution_test.go:32: lazyAdder.Execute redeclared in this block
	previous declaration at ./solution.go:74
FAIL	_/tmp/d20161129-30451-3w4d6r [build failed]
# _/tmp/d20161129-30451-3w4d6r
./solution_test.go:15: adder redeclared in this block
	previous declaration at ./solution.go:15
./solution_test.go:19: adder.Execute redeclared in this block
	previous declaration at ./solution.go:40
./solution_test.go:27: lazyAdder redeclared in this block
	previous declaration at ./solution.go:52
./solution_test.go:32: lazyAdder.Execute redeclared in this block
	previous declaration at ./solution.go:74
FAIL	_/tmp/d20161129-30451-3w4d6r [build failed]
# _/tmp/d20161129-30451-3w4d6r
./solution_test.go:15: adder redeclared in this block
	previous declaration at ./solution.go:15
./solution_test.go:19: adder.Execute redeclared in this block
	previous declaration at ./solution.go:40
./solution_test.go:27: lazyAdder redeclared in this block
	previous declaration at ./solution.go:52
./solution_test.go:32: lazyAdder.Execute redeclared in this block
	previous declaration at ./solution.go:74
FAIL	_/tmp/d20161129-30451-3w4d6r [build failed]
# _/tmp/d20161129-30451-3w4d6r
./solution_test.go:15: adder redeclared in this block
	previous declaration at ./solution.go:15
./solution_test.go:19: adder.Execute redeclared in this block
	previous declaration at ./solution.go:40
./solution_test.go:27: lazyAdder redeclared in this block
	previous declaration at ./solution.go:52
./solution_test.go:32: lazyAdder.Execute redeclared in this block
	previous declaration at ./solution.go:74
FAIL	_/tmp/d20161129-30451-3w4d6r [build failed]
# _/tmp/d20161129-30451-3w4d6r
./solution_test.go:15: adder redeclared in this block
	previous declaration at ./solution.go:15
./solution_test.go:19: adder.Execute redeclared in this block
	previous declaration at ./solution.go:40
./solution_test.go:27: lazyAdder redeclared in this block
	previous declaration at ./solution.go:52
./solution_test.go:32: lazyAdder.Execute redeclared in this block
	previous declaration at ./solution.go:74
FAIL	_/tmp/d20161129-30451-3w4d6r [build failed]
# _/tmp/d20161129-30451-3w4d6r
./solution_test.go:15: adder redeclared in this block
	previous declaration at ./solution.go:15
./solution_test.go:19: adder.Execute redeclared in this block
	previous declaration at ./solution.go:40
./solution_test.go:27: lazyAdder redeclared in this block
	previous declaration at ./solution.go:52
./solution_test.go:32: lazyAdder.Execute redeclared in this block
	previous declaration at ./solution.go:74
FAIL	_/tmp/d20161129-30451-3w4d6r [build failed]
# _/tmp/d20161129-30451-3w4d6r
./solution_test.go:15: adder redeclared in this block
	previous declaration at ./solution.go:15
./solution_test.go:19: adder.Execute redeclared in this block
	previous declaration at ./solution.go:40
./solution_test.go:27: lazyAdder redeclared in this block
	previous declaration at ./solution.go:52
./solution_test.go:32: lazyAdder.Execute redeclared in this block
	previous declaration at ./solution.go:74
FAIL	_/tmp/d20161129-30451-3w4d6r [build failed]
# _/tmp/d20161129-30451-3w4d6r
./solution_test.go:15: adder redeclared in this block
	previous declaration at ./solution.go:15
./solution_test.go:19: adder.Execute redeclared in this block
	previous declaration at ./solution.go:40
./solution_test.go:27: lazyAdder redeclared in this block
	previous declaration at ./solution.go:52
./solution_test.go:32: lazyAdder.Execute redeclared in this block
	previous declaration at ./solution.go:74
FAIL	_/tmp/d20161129-30451-3w4d6r [build failed]

История (2 версии и 0 коментара)

Александър обнови решението на 29.11.2016 15:57 (преди над 1 година)

+package main
+
+import (
+ "errors"
+ "fmt"
+ "sync"
+ "time"
+)
+
+// ############ TASK 1 #############
+
+type Task interface {
+ Execute(int) (int, error)
+}
+type adder struct {
+ augend int
+}
+type executor struct {
+ tasks []Task
+}
+
+func (ex executor) Execute(number int) (int, error) {
+ var result int
+ var err error
+ if len(ex.tasks) == 0 {
+ return 0, errors.New("some err")
+ }
+ for i, task := range ex.tasks {
+ if i == 0 {
+ result, err = task.Execute(number)
+ } else {
+ result, err = task.Execute(result)
+ }
+ if err != nil {
+ return 0, errors.New("some err")
+ }
+ }
+ return result, nil
+}
+func (a adder) Execute(addend int) (int, error) {
+ result := a.augend + addend
+ if result > 127 {
+ return 0, fmt.Errorf("Result %d exceeds the adder threshold", a)
+ }
+ return result, nil
+}
+func Pipeline(tasks ...Task) Task {
+ return &executor{tasks}
+}
+
+// ############ TASK 2 #############
+type lazyAdder struct {
+ adder
+ delay time.Duration
+}
+type executor2 struct {
+ tasks []Task
+}
+
+func (ex executor2) Execute(number int) (int, error) {
+ if len(ex.tasks) == 0 {
+ return 0, errors.New("some err")
+ }
+ c := make(chan int, len(ex.tasks))
+
+ for _, task := range ex.tasks {
+ go func() {
+ res, _ := task.Execute(number)
+ c <- res
+ }()
+ }
+ return <-c, nil
+}
+func (la lazyAdder) Execute(addend int) (int, error) {
+ time.Sleep(la.delay * time.Millisecond)
+ return la.adder.Execute(addend)
+}
+func Fastest(tasks ...Task) Task {
+ return &executor2{tasks}
+}
+
+// ############ TASK 3 #############
+type executor3 struct {
+ task Task
+ timeout time.Duration
+}
+
+func (ex executor3) Execute(number int) (int, error) {
+ type result struct {
+ res int
+ err error
+ }
+ c := make(chan result, 1)
+ go func() {
+ res, err := ex.task.Execute(number)
+ c <- result{res, err}
+ }()
+ select {
+ case res := <-c:
+ if res.err != nil {
+ return res.res, nil
+ }
+ return 0, res.err
+ case <-time.After(ex.timeout):
+ return 0, errors.New("some timeout err")
+ }
+ return 0, nil
+}
+func Timed(task Task, timeout time.Duration) Task {
+ return &executor3{task, timeout}
+}
+
+// ############ TASK 4 #############
+type executor4 struct {
+ tasks []Task
+ f func([]int) int
+}
+
+func (ex executor4) Execute(number int) (int, error) {
+ if len(ex.tasks) == 0 {
+ return 0, errors.New("some err")
+ }
+ type result struct {
+ res int
+ err error
+ }
+ c := make(chan result, len(ex.tasks))
+ var wg sync.WaitGroup
+ wg.Add(len(ex.tasks))
+ for _, task := range ex.tasks {
+ go func() {
+ res, err := task.Execute(number)
+ c <- result{res, err}
+ wg.Done()
+ }()
+ }
+ wg.Wait()
+ close(c)
+ results := make([]int, 0)
+ for res := range c {
+ results = append(results, res.res)
+ if res.err != nil {
+ return 0, errors.New("big error here")
+ }
+ }
+ return ex.f(results), nil
+}
+func ConcurrentMapReduce(reduce func(results []int) int, tasks ...Task) Task {
+ return &executor4{tasks, reduce}
+}
+
+// ############ TASK 5 #############
+// NOT DONE
+type executor5 struct {
+}
+
+func (ex executor5) Execute(number int) (int, error) {
+ return 0, nil
+}
+func GreatestSearcher(errorLimit int, tasks <-chan Task) Task {
+ return &executor5{}
+}

Александър обнови решението на 29.11.2016 15:58 (преди над 1 година)

package main
import (
"errors"
"fmt"
"sync"
"time"
)
// ############ TASK 1 #############
type Task interface {
Execute(int) (int, error)
}
type adder struct {
augend int
}
type executor struct {
tasks []Task
}
func (ex executor) Execute(number int) (int, error) {
var result int
var err error
if len(ex.tasks) == 0 {
return 0, errors.New("some err")
}
for i, task := range ex.tasks {
if i == 0 {
result, err = task.Execute(number)
} else {
result, err = task.Execute(result)
}
if err != nil {
return 0, errors.New("some err")
}
}
return result, nil
}
func (a adder) Execute(addend int) (int, error) {
result := a.augend + addend
if result > 127 {
return 0, fmt.Errorf("Result %d exceeds the adder threshold", a)
}
return result, nil
}
func Pipeline(tasks ...Task) Task {
return &executor{tasks}
}
// ############ TASK 2 #############
type lazyAdder struct {
adder
delay time.Duration
}
type executor2 struct {
tasks []Task
}
func (ex executor2) Execute(number int) (int, error) {
if len(ex.tasks) == 0 {
return 0, errors.New("some err")
}
c := make(chan int, len(ex.tasks))
for _, task := range ex.tasks {
go func() {
res, _ := task.Execute(number)
c <- res
}()
}
return <-c, nil
}
func (la lazyAdder) Execute(addend int) (int, error) {
time.Sleep(la.delay * time.Millisecond)
return la.adder.Execute(addend)
}
func Fastest(tasks ...Task) Task {
return &executor2{tasks}
}
// ############ TASK 3 #############
type executor3 struct {
task Task
timeout time.Duration
}
func (ex executor3) Execute(number int) (int, error) {
type result struct {
res int
err error
}
c := make(chan result, 1)
go func() {
res, err := ex.task.Execute(number)
c <- result{res, err}
}()
select {
case res := <-c:
if res.err != nil {
return res.res, nil
}
return 0, res.err
case <-time.After(ex.timeout):
return 0, errors.New("some timeout err")
}
return 0, nil
}
func Timed(task Task, timeout time.Duration) Task {
return &executor3{task, timeout}
}
// ############ TASK 4 #############
type executor4 struct {
tasks []Task
f func([]int) int
}
func (ex executor4) Execute(number int) (int, error) {
if len(ex.tasks) == 0 {
return 0, errors.New("some err")
}
type result struct {
res int
err error
}
c := make(chan result, len(ex.tasks))
var wg sync.WaitGroup
wg.Add(len(ex.tasks))
for _, task := range ex.tasks {
go func() {
res, err := task.Execute(number)
c <- result{res, err}
wg.Done()
}()
}
wg.Wait()
close(c)
results := make([]int, 0)
for res := range c {
results = append(results, res.res)
if res.err != nil {
return 0, errors.New("big error here")
}
}
return ex.f(results), nil
}
func ConcurrentMapReduce(reduce func(results []int) int, tasks ...Task) Task {
return &executor4{tasks, reduce}
}
// ############ TASK 5 #############
// NOT DONE
type executor5 struct {
}
func (ex executor5) Execute(number int) (int, error) {
return 0, nil
}
func GreatestSearcher(errorLimit int, tasks <-chan Task) Task {
return &executor5{}
-}
+}
+func main() {
+ if res, err := Pipeline(adder{50}, adder{60}).Execute(10); err != nil {
+ fmt.Printf("The pipeline returned an error\n")
+ } else {
+ fmt.Printf("The pipeline returned %d\n", res)
+ }
+ f := Fastest(
+ lazyAdder{adder{20}, 500},
+ lazyAdder{adder{50}, 300},
+ adder{41},
+ )
+ res, err := f.Execute(1)
+ fmt.Println(res, err)
+ _, e1 := Timed(lazyAdder{adder{20}, 50}, 2*time.Millisecond).Execute(2)
+ r2, e2 := Timed(lazyAdder{adder{20}, 50}, 300*time.Millisecond).Execute(2)
+ fmt.Println(e1)
+ fmt.Println(r2, e2)
+ reduce := func(results []int) int {
+ smallest := 128
+ for _, v := range results {
+ if v < smallest {
+ smallest = v
+ }
+ }
+ return smallest
+ }
+
+ mr := ConcurrentMapReduce(reduce, adder{30}, adder{50}, adder{20})
+ if res, err := mr.Execute(5); err != nil {
+ fmt.Printf("We got an error!\n")
+ } else {
+ fmt.Printf("The ConcurrentMapReduce returned %d\n", res)
+ }
+ tasks := make(chan Task)
+ gs := GreatestSearcher(2, tasks)
+
+ go func() {
+ tasks <- adder{4}
+ tasks <- lazyAdder{adder{22}, 20}
+ tasks <- adder{125}
+ time.Sleep(50 * time.Millisecond)
+ tasks <- adder{32}
+
+ tasks <- Timed(lazyAdder{adder{100}, 2000}, 20*time.Millisecond)
+
+ close(tasks)
+ }()
+ result, err := gs.Execute(10)
+ fmt.Println(result)
+}