-
Notifications
You must be signed in to change notification settings - Fork 0
/
primes.go
66 lines (53 loc) · 1.15 KB
/
primes.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
package main
type PrimesGenerator struct {
primes chan uint64
terminate chan struct{}
}
func PrimeFactors(number uint64) []uint64 {
results := make([]uint64, 0, 16)
primes := Primes()
defer primes.Close()
for prime := primes.Next(); prime*prime <= number; prime = primes.Next() {
if number%prime == 0 {
results = append(results, prime)
}
}
if len(results) == 0 {
return append(results, number)
}
return results
}
func Primes() *PrimesGenerator {
primes := &PrimesGenerator{make(chan uint64), make(chan struct{})}
go calculatePrimes(primes.primes, primes.terminate)
return primes
}
func (p *PrimesGenerator) Next() uint64 {
return <-p.primes
}
func (p *PrimesGenerator) Close() {
p.terminate <- struct{}{}
}
func calculatePrimes(ch chan uint64, terminate chan struct{}) {
ch <- 2
primes := make([]uint64, 1, 1024)
primes[0] = 2
for x := uint64(3); ; x += 2 {
prime := true
for i := 1; i < len(primes) && primes[i]*primes[i] <= x; i++ {
if x%primes[i] == 0 {
prime = false
break
}
}
if prime {
primes = append(primes, x)
select {
case ch <- x:
case <-terminate:
close(ch)
return
}
}
}
}