Euler#12,我的Python程序出了什么问题?

时间:2015-07-21 21:20:59

标签: python python-3.4

第12个问题是:

  

通过添加自然数来生成三角数的序列。所以第7个三角形数字是1 + 2 + 3 + 4 + 5 + 6 + 7   = 28.前十个术语是:

     

1,3,6,10,15,21,28,36,45,55,......

     

让我们列出前七个三角形数字的因子:

     

1:1 3:1,3 6:1,2,3,6 10:1,2,5,10 15:1,3,5,15 21:1,3,7,21 28:   1,2,4,7,14,28我们可以看到28是第一个三角形数   五个以上的除数。

     

超过五个的第一个三角形数字的值是多少   一百个除数?

我在Python 3.4中的程序

def Nfactor(n):
    k=2
    c=0
    while k<=n:
        if n%k==0:
          n=n//k
          c+=1
        else:
            k=k+1       
    return c

a=1    
for i in range(10**6):
    a+=i
    if Nfactor(a)>=500:
        print(a)
        break

我等了10多分钟才得到答案。而对于我自己的我的程序并不是太糟糕,必须在几秒钟内运行..好吧它让我发疯大声笑我没有发现我的错误。

你能帮我吗?

提前谢谢!

编辑

我现在的解决方案:

import math

def Nfactor(n):
    if n==1:
        return 1
    else:
        c=0

        for i in range(1, int(math.sqrt(n)+1)):
            if n%i==0:
                c+=1
        return c*2

a=0    
for i in range(1,10**6):
    a+=i
    if Nfactor(a)>=500:
        print(a)
        break

4 个答案:

答案 0 :(得分:3)

您很可能无法获得任何输出。

a的最后一个值是499999500001,而NFactor(..)是500的最小数字是2 ^ 500,这是3273390607896141870013189696827599152216642046043064789483291368096133796404674554883270092325904157150886684127560071009217256545885393053328527589376

一些提示(我有一个工作示例,现在运行时间不到一秒,但我想在这里发布它会是一个扰流板):

  • 正如另一个(删除的)答案所指出的,给定数字的素数因子的计数,数字的除数的数量是(每个素数的加数加1)的乘积,即如果a素数因子p出现N次,您可以构建{0}到N+1的{​​{1}}个产品,并结合素数的不同幂。

  • 正如@NightShadeQueen指出的那样,一旦你计算了数字p^N的素数因子分解,就把它保存在缓存中(我使用ndict的映射一个n,它本身从素数映射到它出现的次数。当被要求计算给定数字的素数因子集时,首先检查缓存,然后从2开始扫描以查看是否可以找到第一个因子。然后递归调用该函数,dict除以第一个因子等。

  • 为了找到n的素数因子,没有必要达到n,你可以在n停留

  • 在找到素数因素sqrt(n)中的k)时,您可以检查Nfactor(..)k=2(即2除k=3 ,如果3除以n等),然后以2为步长递增nk之后只测试k的奇数值

  • 如上面评论中所述,以k=2开头,而a=1代替range(1,10**6)

我的解决方案中没有使用;通过使用我最喜欢的搜索引擎找到:

  • i三角形编号为i'th,因此您可以合并a = i * (i+1) / 2i的素因子(删除一次i+1)。以来 2i不会分享您可以使用的任何常见素数因素 甚至从i+1a的除数数中得出i的除数数。

答案 1 :(得分:3)

一些想法......

  1. 如果我读得正确,您就可以有效地测试从2到n的每个数字n。你应该能够只测试sqrt(n)。 (更新:抱歉,我没有想清楚......它需要是n / 2,而不是sqrt(n)。对primality的测试只需要sqrt(n)。)
  2. 在python shell中运行2 ** 500。我想你会发现你的测试不够高。 : - )
  3. 也许会降低...用少量因素测试你的方法?

答案 2 :(得分:3)

您列出了素数,但不列出他们的产品。在定义中,对于28,你有7,14和28,在你的函数中你只计算数字7。

所以Nfactor,按照要求去做,应该是这样的:

def Nfactor(n):
    k=2
    c=2
    while k<n:
        if n%k == 0:
            c+=1
        k=k+1       
    return c

但是有一种更快的方法可以获得这些因素(感谢this page):

from math import sqrt
def Nfactor(n):
    factors = set()
    for x in range(1, int(sqrt(n)) + 1):
        if n % x == 0:
            factors.add(x)
            factors.add(n//x)
     return len(factors)

另外,您没有按照说明操作。您不会将搜索限制为由后续术语总和(1,1 + 2,1 + 2 + 3,1 + 2 + 3 + 4等)定义的数字,而是对每个数字进行测试( for i in range(10**6):)。

要获得这些数字,您可以使用generator(请参阅here),如下所示:

def gen():
    counter = 1
    total = 0
    while True:
        total += counter
        yield total
        counter += 1

然后,您可以执行此操作以找到所需的号码:

g = gen()
for n in g:
    if Nfactor(n) > 500:
        print(n)
        break

答案 3 :(得分:0)

import math
num=2
i=3
def is_notprime(num):
    j=3
    flag=int(math.sqrt(num))   
    while((j<=flag and num>=3)):    
      if num%j==0:    
        return True
        break
      else:
        j=j+2
def check_div(num):
  temp=1
  a=i
  if(num%2==0 and num>1):
    while(num%2==0):
        num=num/2
        temp+=1
  for j in range(3,int((num+5)/2),2):
    count=1
    if((is_notprime(num) and num>1) or num==j):
      while num%j==0:
        num=num/j
        count+=1
    elif num>1:
      temp=temp*2
      break

    temp=temp*count
  print("divisor is and  %d ans is %d" %(temp,a))
  return(temp)
while(i>=1):
  if(check_div(i)>5):
    break
  num+=1
  i=num*(num+1)/2