Skip to content

Commit

Permalink
fix out of order generation and filtering.
Browse files Browse the repository at this point in the history
  • Loading branch information
asakatida committed Mar 28, 2022
1 parent 9504c36 commit 94cf9ce
Showing 1 changed file with 65 additions and 42 deletions.
107 changes: 65 additions & 42 deletions primes.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,71 +2,94 @@ package main

import (
"flag"
"log"
"fmt"
)

func runCounter(counter chan<- uint, prime uint) {
for count := prime * 2; ; count += prime {
counter <- count
func generate(ch chan<- uint, start, end uint) {
defer close(ch)
if end == 0 {
for i := uint(3); i < start<<1; i += 2 {
ch <- i
}
} else {
for i := uint(3); i < end; i += 2 {
ch <- i
}
}
}

func newCounter(prime uint) <-chan uint {
counter := make(chan uint)
go runCounter(counter, prime)
return counter
func sieve(src <-chan uint, dst chan<- uint, prime uint) {
defer close(dst)
for i := range src {
if i%prime != 0 {
dst <- i
}
}
}

func stepCounter(h map[uint]<-chan uint, counter <-chan uint) {
c := <-counter
if h[c], counter = counter, h[c]; counter != nil {
go stepCounter(h, counter)
}
func sieveChannel(src <-chan uint, start, prime uint) <-chan uint {
src_prime := make(chan uint, 1)
go sieve(src, src_prime, prime)
return src_prime
}

func insertPrime(primes chan<- uint, h map[uint]<-chan uint, gC uint) {
primes <- gC
stepCounter(h, newCounter(gC))
func nextPrime(src <-chan uint, prime uint) uint {
for i := range src {
return i
}
return prime
}

func primeStep(primes chan<- uint, h map[uint]<-chan uint, gC uint) {
counter := h[gC]
if counter == nil {
insertPrime(primes, h, gC)
} else {
stepCounter(h, counter)
delete(h, gC)
func nextPrimeSend(src <-chan uint, dst chan<- uint, prime uint) uint {
for i := range src {
dst <- i
return i
}
return prime
}

func primeLoop(primes chan<- uint) {
primes <- 2
h := make(map[uint]<-chan uint)
for gC := 3; ; gC += 2 {
primeStep(primes, h, uint(gC))
func filterRoutine5(src <-chan uint, dst chan<- uint, start, end, prime uint) {
defer close(dst)
for last_prime := uint(0); prime < start && last_prime != prime; {
last_prime = prime
src = sieveChannel(src, start, prime)
prime = nextPrime(src, prime)
}
if start <= 2 {
dst <- 2
if end > 0 {
dst <- prime
}
}
if end == 0 {
for range src {
}
}
for last_prime := uint(0); last_prime != prime; {
last_prime = prime
src = sieveChannel(src, start, prime)
prime = nextPrimeSend(src, dst, prime)
}
}

func makePrimes() <-chan uint {
primes := make(chan uint)
go primeLoop(primes)
return primes
func startSieve(start, end uint) <-chan uint {
src := make(chan uint, 1)
go generate(src, start, end)
dst := make(chan uint, 1)
go filterRoutine5(src, dst, start, end, <-src)
return dst
}

func main() {
var start uint
var end uint
flag.UintVar(&start, "start", 0, "usage")
flag.UintVar(&end, "end", 10, "usage")
flag.UintVar(&end, "end", 0, "usage")
flag.Parse()
primes := makePrimes()
for {
prime := <-primes
if prime > end {
return
}
if prime >= start {
log.Println(prime)
}
if end > 0 && end <= 2 {
return
}
for prime := range startSieve(start, end) {
fmt.Print(prime, "\n")
}
}

0 comments on commit 94cf9ce

Please sign in to comment.