name hat geschrieben:
Scheint zu funktionieren, schaut aber eher, naja, nicht sehr uebersichtlich aus. Koenntest du den Algorithmus bitte einfach so, bzw mit Pseudocode erklaeren?
Nun, die mathematischen Hintergründe halte ich in diesem Forum für "beyond the scope", nur soviel, es ist etwas "Selbstgestricktes" und soll leicht portierbar sein
Habe es noch mal als Klasse implementiert..
Code: Alles auswählen
import math,time
class primetest(object):
"""
Primfaktorenzerlegung, Primzahlentest, Primzahlensuche
(c)2008 Qubit
hannover.post@gmail.com
"""
__time = {
'fak': 0,
'is_prime': 0,
'primes': 0
}
def __getattr__(self,attr):
attrs = {
't_fak': self.__time['fak'],
't_is_prime': self.__time['is_prime'],
't_primes': self.__time['primes']
}
get = attrs.get(attr,None)
if not get == None:
return tuple(str('%.3f,sec' %(get)).split(','))
else:
object.__getattribute__(self,attr)
def __fak(self,z,mode):
primfak=[]
m = 0
found = 0
limit = int((math.sqrt(z)-1)/2)
while z % 2 == 0:
if mode == 1 and not z == 2: return [z,False]
z = z/2
primfak.append((2,z))
i = (z-1)/2
while (i-1) % 3 == 0:
if mode == 1 and not i == 1: return [z,False]
i = (i - 1)/3
primfak.append((3,2*i+1))
if (i-2) % 3 == 0:
u = (i-2)/3
s = 2
if (i-3) % 3 == 0:
u = (i-3)/3
s = 3
while m < u and m < limit:
if s == 2:
if (u-m) % (6*m+5) == 0:
n = (u-m) / (6*m+5)
m0 = 3*m + 2
n0 = 3*n
primfak.append((2*m0+1,2*n0+1))
found = 1
if not found and (u-5*m-5) % (6*m+7) == 0:
n = (u-5*m-5) / (6*m+7)
m0 = 3*m + 3
n0 = 3*n + 2
primfak.append((2*m0+1,2*n0+1))
found = 1
if s == 3:
if (u-5*m-3) % (6*m+5) == 0:
n = (u-5*m-3) / (6*m+5)
m0 = 3*m + 2
n0 = 3*n + 2
primfak.append((2*m0+1,2*n0+1))
found = 1
if not found and (u-m) % (6*m+7) == 0:
n = (u-m) / (6*m+7)
m0 = 3*m + 3
n0 = 3*n
primfak.append((2*m0+1,2*n0+1))
found = 1
if found == 1:
if mode == 1 and not 2*m0+1 == z:
return [z,False]
i = n0
while (i-1) % 3 == 0:
i = (i - 1)/3
primfak.append((3,2*i+1))
if (i-2) % 3 == 0:
u = (i-2)/3
s = 2
if (i-3) % 3 == 0:
u = (i-3)/3
s = 3
limit = int((math.sqrt(2*i+1)-1)/2)
found = 0
m -= 1
m += 1
if len(primfak) > 0:
x = [x[0] for x in primfak]+[primfak[-1][1]]
if x[-1] == 1: x.pop()
else: x=[z]
return x
def __is_prime(self,z): return len(self.__fak(z,mode=1)) == 1
def __primes(self,bis,von): return filter(self.__is_prime, range(von,bis+1))
def fak(self,z=2):
t_start = time.clock()
res = self.__fak(z,mode=0)
t_elapsed = time.clock() - t_start
self.__time['fak'] = t_elapsed
return res
def is_prime(self,z=2):
t_start = time.clock()
res = self.__is_prime(z)
t_elapsed = time.clock() - t_start
self.__time['is_prime'] = t_elapsed
return res
def primes(self,bis=2,von=2):
t_start = time.clock()
res = self.__primes(bis,von)
t_elapsed = time.clock() - t_start
self.__time['primes'] = t_elapsed
return res
>>> prim=primetest()
>>> prim.is_prime(348234823482389479)
False
>>> prim.t_is_prime
('0.350', 'sec')
>>> prim.fak(348234823482389479)
[413243, 842687773253L]
>>> prim.t_fak
('2.057', 'sec')
>>> prim.is_prime(123456789)
False
>>> prim.t_is_prime
('0.000', 'sec')
>>> prim.fak(123456789)
[3, 3, 3607, 3803]
>>> prim.t_fak
('0.001', 'sec')
>>> res = prim.primes(10000)
>>> prim.t_primes
('0.142', 'sec')
>>> res[-10:]
[9887, 9901, 9907, 9923, 9929, 9931, 9941, 9949, 9967, 9973]
>>> len(res)
1229
>>>