first commit
This commit is contained in:
78
util/python/sieve.py
Normal file
78
util/python/sieve.py
Normal file
@@ -0,0 +1,78 @@
|
||||
from math import sqrt, floor
|
||||
|
||||
class sieve:
|
||||
|
||||
def __init__(self):
|
||||
self.sieve = [False]
|
||||
self._length = 1
|
||||
self._target = 1
|
||||
|
||||
def run(self, n):
|
||||
self._target = n
|
||||
self._elongate()
|
||||
|
||||
def get(self, n):
|
||||
if n > self._length:
|
||||
self.run(n)
|
||||
return self.sieve[n-1]
|
||||
|
||||
def _elongate(self):
|
||||
length = self._length
|
||||
target = self._target
|
||||
diff = target - length
|
||||
if diff > 0:
|
||||
self.sieve += [True for _ in range(diff)]
|
||||
for i in range(floor(sqrt(target))):
|
||||
if self.sieve[i]:
|
||||
_floor = length//(i+1)
|
||||
_ceil = target//(i+1)
|
||||
for j in range(_floor, _ceil):
|
||||
actual = (i+1)*(j+1)-1
|
||||
if actual > i+1:
|
||||
self.sieve[actual] = False
|
||||
self._length = target
|
||||
|
||||
class extended_sieve:
|
||||
|
||||
def __init__(self):
|
||||
self.sieve = [[False, 1, []]]
|
||||
self._length = 1
|
||||
self._target = 1
|
||||
self.prerun_step = 1000
|
||||
|
||||
def run(self, n):
|
||||
self._target = n
|
||||
self._elongate()
|
||||
|
||||
def get(self, n):
|
||||
if n > self._length:
|
||||
self.run(n+self.prerun_step)
|
||||
prime_decomp = {}
|
||||
for e in self.sieve[n-1][2]:
|
||||
if e in list(prime_decomp.keys()):
|
||||
prime_decomp[e] += 1
|
||||
else:
|
||||
prime_decomp[e] = 1
|
||||
return [self.sieve[n-1][0], prime_decomp]
|
||||
|
||||
def _elongate(self):
|
||||
length = self._length
|
||||
target = self._target
|
||||
diff = target - length
|
||||
if diff > 0:
|
||||
self.sieve += [[True, length+i+1, []] for i in range(diff)]
|
||||
for i in range(target):
|
||||
if self.sieve[i][0]:
|
||||
if i+1 > length:
|
||||
self.sieve[i][2] += [i+1]
|
||||
_floor = length//(i+1)
|
||||
_ceil = target//(i+1)
|
||||
for j in range(_floor, _ceil):
|
||||
actual = (i+1)*(j+1)-1
|
||||
if actual > i+1:
|
||||
old_entry = self.sieve[actual]
|
||||
self.sieve[actual] = [False, old_entry[1]//(i+1), old_entry[2]+[i+1]]
|
||||
elif self.sieve[i][1] != 1:
|
||||
old_entry = self.sieve[i]
|
||||
self.sieve[i] = [False, 1, old_entry[2]+self.sieve[old_entry[1]-1][2]]
|
||||
self._length = target
|
||||
Reference in New Issue
Block a user