sieve1.go 928 B

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. package kata
  2. // Based on the Go classical concurrent prime sieve
  3. // See https://golang.org/test/chan/sieve1.go
  4. func Primes(limit int) []int {
  5. // Generate numbers from 2 to limit, included.
  6. gen := func(ch chan<- int, limit int) {
  7. for i := 2; i <= limit; i++ {
  8. ch <- i
  9. }
  10. close(ch)
  11. }
  12. // Remove divisible numbers
  13. // - in: numbers source
  14. // - out: numbers sink
  15. // - prime: prime by which to attempt modulo
  16. filter := func(in <-chan int, out chan<- int, prime int) {
  17. for {
  18. candidate, ok := <-in
  19. // Source was closed.
  20. if !ok {
  21. break
  22. }
  23. if candidate%prime != 0 {
  24. out <- candidate
  25. }
  26. }
  27. close(out)
  28. }
  29. genChan := make(chan int)
  30. go gen(genChan, limit)
  31. var primes []int
  32. for i := 0; ; i++ {
  33. prime, ok := <-genChan
  34. if !ok {
  35. break
  36. }
  37. primes = append(primes, prime)
  38. filterChan := make(chan int)
  39. go filter(genChan, filterChan, prime)
  40. genChan = filterChan
  41. }
  42. return primes
  43. }