Python项目Euler3
我是python新手,我试图通过Euler项目帮助我的女朋友学习编码,我建议她从python开始。不幸的是,在问题3上,我们出现了一个奇怪的错误 对于寻找较小数的素数因子,这似乎很有效,但试图找到600851475143的素数因子却令人窒息 我觉得python非常宽容最大整数值,所以我不知道为什么它在这里不起作用Python项目Euler3,python,Python,我是python新手,我试图通过Euler项目帮助我的女朋友学习编码,我建议她从python开始。不幸的是,在问题3上,我们出现了一个奇怪的错误 对于寻找较小数的素数因子,这似乎很有效,但试图找到600851475143的素数因子却令人窒息 我觉得python非常宽容最大整数值,所以我不知道为什么它在这里不起作用 def is_prime (n) : for i in range (2, n) : if n % i == 0: return 0
def is_prime (n) :
for i in range (2, n) :
if n % i == 0:
return 0
return 1
n = 600851475143
for i in range (1, n) :
if n % i == 0 :
if is_prime (i) == 1 :
print i
如果有人能正确地引导我,我将非常感激
大卫
编辑:我很清楚这一切是多么次优 请参见此算法,通过除以因子来遍历数字,这样效率更高:
while num > 1:
if num % div == 0:
num /= div
div -= 1
div += 1
找到大数的素因子不是一件小事。Scriptography基于两个键的乘积,这两个键足够大,以至于最大的并行计算机会被它们卡住。当计算能力或计算方法有所改进时,您只需使用更大的灵敏性来保证安全 试算法运算速度非常快,对于较大的数字,有像布伦特那样的试错法可以更进一步。
我附加的代码在0.1秒内找到600851475143=[7183914716857],但对于较大的数字,它会阻塞相同的代码。
它使用高达1米的试算法,然后切换到布伦特的方法。
我无法解释Brent,我只是复制了代码
#Py3.4
from fractions import gcd
from random import randint
from time import clock
def brent(N):
# brent returns a divisor, not guaranteed to be prime
if N%2==0: return 2
y,c,m = randint(1, N-1),randint(1, N-1),randint(1, N-1)
g,r,q = 1,1,1
while g==1:
x = y
for i in range(r):
y = ((y*y)%N+c)%N
k = 0
while (k<r and g==1):
ys = y
for i in range(min(m,r-k)):
y = ((y*y)%N+c)%N
q = q*(abs(x-y))%N
g = gcd(q,N)
k = k + m
r = r*2
if g==N:
while True:
ys = ((ys*ys)%N+c)%N
g = gcd(abs(x-ys),N)
if g>1: break
return g
def factorize(n1):
if n1<=0: return []
if n1==1: return [1]
n=n1
b=[]
p=0
mx=1000000
while n % 2 ==0 : b.append(2);n//=2
while n % 3 ==0 : b.append(3);n//=3
i=5
inc=2
while i <=mx:
while n % i ==0 : b.append(i); n//=i
i+=inc
inc=6-inc
while n>mx:
p1=n
#iterate until divisor is prime
while p1!=p:
p=p1
p1=brent(p)
print(p1)
b.append(p1);n//=p1
if n!=1:b.append(n)
b.sort()
return b
from functools import reduce
from sys import argv
def main():
if len(argv)==2:
n=int(argv[1])
else:
n=int(eval(input(" Integer to factorize? ")))
t1=clock()
li=factorize(n)
print (n,"= ",li)
print(clock()-t1, " seconds")
print ("n - product of factors = ",n - reduce(lambda x,y :x*y ,li))
if __name__ == "__main__":
main()
#Py3.4
从分数导入gcd
从随机导入randint
从时间输入时钟
布伦特(北):
#brent返回一个除数,不能保证是素数
如果N%2==0:返回2
y、 c,m=randint(1,N-1),randint(1,N-1),randint(1,N-1)
g、 r,q=1,1,1
当g==1时:
x=y
对于范围(r)内的i:
y=((y*y)%N+c)%N
k=0
while(k1:break)
返回g
def分解(n1):
如果n1因为没有人回答明显的问题,请使用xrange
而不是range
:
def is_prime (n) :
for i in xrange (2, n) :
if n % i == 0:
return 0
return 1
n = 600851475143
for i in xrange (1, n) :
if n % i == 0 :
if is_prime (i) == 1 :
print i
但请记住,这仍然非常缓慢,但您不会遇到内存错误。Python正在工作,但6000亿次不简单的迭代将“永远”花费。我很确定情况并非如此,如果我在检查n%I==0之前输入print I,仍然不会输出任何内容。Python无法为范围(2600851475143)分配一个巨大的列表
。切换到xrange
,然后继续调试。值得一提的是,Project Euler问题并不是为了介绍编程概念而设计的。它们只是设计智能算法的一个练习,暴力尝试可能会失败,就像这里所做的那样。您尝试过用xrange代替range吗?请参阅。谢谢你,但我只是想知道为什么它不起作用,似乎range是个问题,用xrange替代它已经解决了。谢谢你,是的,这正是我想要的。我想,优化会在以后出现!