项目Euler#27 Python

时间:2014-08-16 22:34:16

标签: python algorithm list

项目欧拉问题#27如下:

  欧拉发现了非凡的二次公式:

     

n²+ n + 41

     

事实证明,该公式将产生40个素数   连续值n = 0到39.然而,当n = 40时,402 + 40 + 41 =   40(40 + 1)+ 41可被41整除,当然n = 41时,41 + 2   41 + 41显然可以被41整除。

     

发现令人难以置信的公式n² - 79n + 1601,产生了   80个素数为连续值n = 0到79.产品的   系数-79和1601是-126479。

     

考虑形式的二次方:

     

n²+ an + b,其中| a | < 1000和| b | < 1000

     

其中| n |是n的模量/绝对值,例如| 11 | = 11和| -4 | =   4找到二次系数的乘积a和b的乘积   表达式,它产生连续的最大素数   n的值,从n = 0开始。

这是我的解决方案:

from math import sqrt, fabs

def eSieve(rnge):
    rootedrange = int(sqrt(rnge))
    mydict = dict([(_, True) for _ in range(2, rootedrange)])
    for i in range(2, rootedrange):
        if mydict[i] == True:
            for j in range(i**2, rnge, i):
                mydict[j] = False
    mylist = []
    for key in mydict.keys():
        if mydict[key] is True:
            mylist.append(key)
    return mylist

primes = eSieve(87400)

def isPrime(n):
    i = 0
    while primes[i] <= n:
        if primes[i] == n: return True
        i+=1
    return False

arange = 0
brange = 0
nrange = 0
for a in range(-1000, 1001):
    for b in range(-1000, 1001):
        n = 0
        formula = n*n + a*n + b
        print(formula)
        while(isPrime(fabs(formula))):
            n+=1

        if n > nrange:
            arange = a
            brange = b
            crange = c

print(arange * brange)

我不知道为什么它会不断抛出这个错误:

Traceback (most recent call last):
  File "D:\Programming\ProjectEuler\p27.py", line 33, in <module>
    while(isPrime(fabs(formula))):
  File "D:\Programming\ProjectEuler\p27.py", line 20, in isPrime
    while primes[i] <= n:
IndexError: list index out of range

任何人都可以告诉我的程序在列表范围之外的位置和方式是什么?这是非常不正常的。为什么会这样?

2 个答案:

答案 0 :(得分:3)

让我们看看如果你想看看1000000是否是一个素数会发生什么:

i = 0
while primes[i] <= n:
    if primes[i] == n: return True
    i+=1

return False

所有过筛的素数都不大于1000000,因此您的while条件永远不会满足。 Python的第一条规则是从不使用while循环(除非你不能使用任何其他循环)。在这里,您可以轻松地将其替换为for

for i in primes:
    if i == n:
        return True

return False

但这正是in运算符设置为替换的原因:

return n in primes

除了isPrime重新实现Python核心功能n in primes之外,还有 随着项目数量的增长,item in list慢于item in set

因此,对于几乎最少打字的最快代码,您可以这样做:

>>> primes = eSieve(87400)
>>> prime_set = set(primes)
>>> 13 in prime_set
True
>>> # or if you want a function:
>>> is_prime = prime_set.__contains__
>>> is_prime(13)
True
如果给定值在set中,则set的{​​{3}}魔术方法返回true - 这比在函数中包装in运算符要快得多

答案 1 :(得分:0)

如果isPrime(n)返回n是否在先前创建的列表primes中,那么您可以轻松地写出:

def isPrime(n):
    return n in primes

(你的解决方案失败了,因为你的主要列表对于n = 1000来说太短了。最大的素数是293,因此总是满足while条件。但过了一段时间你想比较{{ 1}} primes[62],超出范围。)