这是Project Euler的一个问题:
如果我们计算^ 2 mod 6为0< = a< = 5,我们得到:0,1,4,3,4,1。
“a”的最大值,使得^ 2 mod 6 = a为4。 我们称M(n)为a的最大值。 n使得a ^ 2 mod n = a。 所以M(6)= 4。
找到M(n)为1< = n< = 10 ^ 7。
到目前为止,这就是我所拥有的:
import time
start = time.time()
from math import sqrt
squares=[]
for numba in xrange(0,10000001/2+2):
squares.append(numba*numba)
def primes1(n):
""" Returns a list of primes < n """
sieve = [True] * (n/2)
for i in xrange(3,int(sqrt(n))+1,2):
if sieve[i/2]:
sieve[i*i/2::i] = [False] * ((n-i*i-1)/(2*i)+1)
return [2] + [2*i+1 for i in xrange(1,n/2) if sieve[i]]
tot=0
gor = primes1(10000001)
def factor1(n):
'''Returns whether a number has more than 1 prime factor'''
boo = False
'''if n in gor:
return True'''
for e in xrange(0,len(gor)):
z=gor[e]
if n%z==0:
if boo:
return False
boo = True
elif z*2>n:
break
return True
for n in xrange(2,10000001):
if factor1(n):
tot+=1
else:
for a in xrange(int(sqrt(n))+1,n/2+1):
if squares[a]%n==a:
tot+=n+1-a
break
print tot
print time.time()-start
我已经尝试过这个代码用于较小的案例并且它完美地工作;然而,做10 ^ 7个病例太慢了。
目前,当n小于20000时,它在大约8秒内运行。 当n小于90000时,它会在大约150秒内运行。
据我所知,如果n小于10 ^ 7,如果不是几天,它将运行数小时。
我已经使用筛子生成素数,这样部分就可以了,我能做些什么来加速其余的代码?
我已经尝试过使用不同的编译器,如psyco,pypy和shedskin。 Psyco提供了最小的增加,脱壳皮肤加速了大约7倍,但是当大量出现时会产生错误,pypy加速最多(大约20-30倍的速度)。但即便如此,它仍然不足以满足它必须经历的案件数量。
编辑:
我添加了
squares=[]
for numba in xrange(0,10000001/2+2):
squares.append(numba*numba)
这预先生成了a
的所有正方形,这样我就不必一遍又一遍地生成相同的正方形。程序变得稍快但仍然不够
答案 0 :(得分:0)
由于内存使用的原因,这可能取决于N
的大小,但在较小的测试中,我通过预先计算因子计数找到了一些改进。所以像这样:
factors = [0]*N
for z in gor:
for n in xrange(1,N):
m = z*n
if m >= N: break
factors[m] += 1
其中N
是10000001,或者你正在使用的任何计数器。
然后代替if factor1(n)
if factors[n] < 2
。