59 lines
1.1 KiB
Go
59 lines
1.1 KiB
Go
|
package primes
|
||
|
|
||
|
type wheel struct {
|
||
|
cache Cache
|
||
|
elements []int64
|
||
|
primes []int64
|
||
|
size int64
|
||
|
offset int
|
||
|
n int64
|
||
|
}
|
||
|
|
||
|
func newWheel6(cache Cache) *wheel {
|
||
|
return &wheel{cache, []int64{2, 4}, []int64{2, 3}, 6, 0, 5}
|
||
|
}
|
||
|
|
||
|
func (s *wheel) resetTo(n int64) {
|
||
|
nn := n + 1
|
||
|
s.n = (nn/s.size)*s.size - 1
|
||
|
s.offset = 0
|
||
|
for s.n+s.elements[s.offset] <= n {
|
||
|
s.next()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (s *wheel) next() int64 {
|
||
|
s.n += s.elements[s.offset]
|
||
|
s.offset = (s.offset + 1) % len(s.elements)
|
||
|
return s.n
|
||
|
}
|
||
|
|
||
|
func (s *wheel) expand() *wheel {
|
||
|
prime := s.primes[len(s.primes)-1]
|
||
|
it := NewIteratorFromCache(s.cache)
|
||
|
for it.Next() && it.Get() <= prime {
|
||
|
}
|
||
|
prime = it.Get()
|
||
|
if s.n <= prime {
|
||
|
return nil
|
||
|
}
|
||
|
primes := append([]int64(nil), s.primes...)
|
||
|
primes = append(primes, prime)
|
||
|
var elements []int64
|
||
|
var v int64 = -1
|
||
|
var inc int64
|
||
|
for i := int64(0); i < prime; i++ {
|
||
|
for _, el := range s.elements {
|
||
|
v += el
|
||
|
inc += el
|
||
|
if 0 != v%prime {
|
||
|
elements = append(elements, inc)
|
||
|
inc = 0
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
exp := &wheel{s.cache, elements, primes, s.size * prime, 0, s.n}
|
||
|
exp.resetTo(s.n)
|
||
|
return exp
|
||
|
}
|