Python项目Euler3

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

我是python新手,我试图通过Euler项目帮助我的女朋友学习编码,我建议她从python开始。不幸的是,在问题3上,我们出现了一个奇怪的错误

对于寻找较小数的素数因子,这似乎很有效,但试图找到600851475143的素数因子却令人窒息

我觉得python非常宽容最大整数值,所以我不知道为什么它在这里不起作用

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替代它已经解决了。谢谢你,是的,这正是我想要的。我想,优化会在以后出现!