def qs(n,verbose=0): if verbose: print "Factoring a",int(log(n,10)+1),"digit number" root2n=isqrt(2*n) bound=int(5*log(n,10)**2) factorbase = [2]+[x for x in prime_sieve(bound) if legendre_symbol(n,x)==1] if verbose: print "Largest Prime Factor used is",factorbase[-1] tsqrt=[] tlog=[] for p in factorbase: ms=int(modular_sqrt(n,p)) tsqrt.append(ms) tlog.append(log(p,10)) xmax = len(factorbase)*60*4 m_val = (xmax * root2n) >> 1 thresh = log(m_val, 10) * 0.735 #ignore small primes min_prime = int(thresh*3) fudge = sum(tlog[i] for i,p in enumerate(factorbase) if p < min_prime)/4 thresh -= fudge roota=int(isqrt(root2n/xmax)) roota=max(3,roota+int(roota&1==0)) smooths=[] partials={} polynomials=0 while 1: while 1: roota=next_prime(roota) if legendre_symbol(n,roota)==1:break polynomials+=1 a = int(roota*roota) b = modular_sqrt(n,roota) b = int((b-(b*b-n)*mod_inv(2*b,roota))%a) c = int((b*b-n)/a) sievesize = 1<<15 s1={};s2={} #set up values for i,p in enumerate(factorbase): ainv=pow(a,p-2,p) sol1=ainv*( tsqrt[i]-b) %p sol2=ainv*(-tsqrt[i]-b) %p sol1-=((xmax+sol1)/p)*p sol2-=((xmax+sol2)/p)*p s1[p]=int(sol1+xmax) s2[p]=int(sol2+xmax) #segmented sieve for low in xrange(-xmax,xmax+1,sievesize+1): high = min(xmax,low+sievesize) size=high - low S=[0.0]*(size+1) #sieve segment for i,p in enumerate(factorbase): if p<min_prime:continue sol1=s1[p] sol2=s2[p] logp=tlog[i] while sol1<=size or sol2<=size: if sol1<=size: S[sol1]+=logp sol1+=p if sol2<=size: S[sol2]+=logp sol2+=p s1[p]=int(sol1-size-1) s2[p]=int(sol2-size-1) #check segment for smooths for i in xrange(0,size+1): if S[i]>thresh: x=i+low tofact=nf=a*x*x+2*b*x+c if nf<0:nf=-nf for p in factorbase: while nf%p==0:nf=int(nf/p) if nf==1: smooths+=[(a*x+b,(tofact,roota))] #check for 1 big factor elif nf in partials: pairv,pairvals=partials[nf] smooths+=[( (a*x+b)*pairv, ( tofact*pairvals[0],roota*pairvals[1]*nf) )] del partials[nf] else: partials[nf]=(a*x+b,(tofact,roota)) if len(smooths)>len(factorbase): break if verbose: print 100*len(smooths)/len(factorbase),'%','using',polynomials,'polynomials','\r', if verbose: print len(smooths),"relations found using",polynomials,"polynomials" return algebra(factorbase,smooths,n)
#By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is 13. #What is the 10001st prime number? import tools p=1 for a in range(0,10001): p = tools.next_prime(p) print p
def qs(n, verbose=0): if verbose: print "Factoring a", int(log(n, 10) + 1), "digit number" root2n = isqrt(2 * n) bound = int(5 * log(n, 10)**2) factorbase = [2] + [ x for x in prime_sieve(bound) if legendre_symbol(n, x) == 1 ] if verbose: print "Largest Prime Factor used is", factorbase[-1] tsqrt = [] tlog = [] for p in factorbase: ms = int(modular_sqrt(n, p)) tsqrt.append(ms) tlog.append(log(p, 10)) xmax = len(factorbase) * 60 * 4 m_val = (xmax * root2n) >> 1 thresh = log(m_val, 10) * 0.735 #ignore small primes min_prime = int(thresh * 3) fudge = sum(tlog[i] for i, p in enumerate(factorbase) if p < min_prime) / 4 thresh -= fudge roota = int(isqrt(root2n / xmax)) roota = max(3, roota + int(roota & 1 == 0)) smooths = [] partials = {} polynomials = 0 while 1: while 1: roota = next_prime(roota) if legendre_symbol(n, roota) == 1: break polynomials += 1 a = int(roota * roota) b = modular_sqrt(n, roota) b = int((b - (b * b - n) * mod_inv(2 * b, roota)) % a) c = int((b * b - n) / a) sievesize = 1 << 15 s1 = {} s2 = {} #set up values for i, p in enumerate(factorbase): ainv = pow(a, p - 2, p) sol1 = ainv * (tsqrt[i] - b) % p sol2 = ainv * (-tsqrt[i] - b) % p sol1 -= ((xmax + sol1) / p) * p sol2 -= ((xmax + sol2) / p) * p s1[p] = int(sol1 + xmax) s2[p] = int(sol2 + xmax) #segmented sieve for low in xrange(-xmax, xmax + 1, sievesize + 1): high = min(xmax, low + sievesize) size = high - low S = [0.0] * (size + 1) #sieve segment for i, p in enumerate(factorbase): if p < min_prime: continue sol1 = s1[p] sol2 = s2[p] logp = tlog[i] while sol1 <= size or sol2 <= size: if sol1 <= size: S[sol1] += logp sol1 += p if sol2 <= size: S[sol2] += logp sol2 += p s1[p] = int(sol1 - size - 1) s2[p] = int(sol2 - size - 1) #check segment for smooths for i in xrange(0, size + 1): if S[i] > thresh: x = i + low tofact = nf = a * x * x + 2 * b * x + c if nf < 0: nf = -nf for p in factorbase: while nf % p == 0: nf = int(nf / p) if nf == 1: smooths += [(a * x + b, (tofact, roota))] #check for 1 big factor elif nf in partials: pairv, pairvals = partials[nf] smooths += [((a * x + b) * pairv, (tofact * pairvals[0], roota * pairvals[1] * nf))] del partials[nf] else: partials[nf] = (a * x + b, (tofact, roota)) if len(smooths) > len(factorbase): break if verbose: print 100 * len(smooths) / len( factorbase), '%', 'using', polynomials, 'polynomials', '\r', if verbose: print len(smooths), "relations found using", polynomials, "polynomials" return algebra(factorbase, smooths, n)