-
Notifications
You must be signed in to change notification settings - Fork 0
/
generate.go
77 lines (63 loc) · 1.3 KB
/
generate.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
67
68
69
70
71
72
73
74
75
76
77
/*
Package primes implements a library for generating prime numbers.
*/
package primes
type signal struct{}
type chanSignal chan signal
func NewChanSignal() chanSignal {
return make(chan signal, 1)
}
func NewSignal() signal {
return signal{}
}
// Generate a slices of prime numbers
// max prime number will be less than maxN
// out will be returning prime numbers
// you can stop generating by send signal via enough <- primes.NewSignal()
func Generate(maxN int, out chan<- int, enough chanSignal) {
if maxN < 2 {
return
}
res_mask := make([]bool, ceilToEven(maxN)/2-1)
for i := range res_mask {
res_mask[i] = true
}
out <- 2
defer close(out)
for i := 0; i < len(res_mask); i++ {
select {
case <-enough:
return
default:
if res_mask[i] == true {
out <- idx2value(i)
markCompositeNumbers(res_mask, i)
}
}
}
}
func markCompositeNumbers(mask []bool, idx int) {
cur_val := idx2value(idx)
for sum := cur_val * 2; sum <= idx2value(len(mask)-1); sum += cur_val {
new_idx, ok := value2idx(sum)
if !ok {
continue
}
mask[new_idx] = false
}
}
func idx2value(idx int) int {
return idx*2 + 3
}
func ceilToEven(v int) int {
if v%2 != 0 {
return v + 1
}
return v
}
func value2idx(value int) (int, bool) {
if value%2 == 0 {
return 0, false
}
return (value - 3) / 2, true
}