代码中的逻辑错误?

时间:2014-01-18 09:50:15

标签: python

  

问题:   3797号有一个有趣的地方。作为素数本身,可以从左到右连续删除数字,并在每个阶段保持素数:3797,797,97和7.同样,我们可以从右到左工作:3797,379,37和3。

     

找到从左到右和从右到左都可截断的仅有的11个素数之和。注意:2,3,5和7不被认为是可截断的素数。

我的代码只能输出前五个这样的数字并显示以下错误:

Traceback (most recent call last):
  File "main.py", line 41, in 
    if check(i) and check(rev(i)):
  File "main.py", line 30, in check
    if sieve[n]:
IndexError: list index out of range

代码:

sieve = [True] * 1000001 # Sieve is faster for 2M primes
def mark(sieve, x):
    for i in xrange(x+x, len(sieve), x):
        sieve[i] = False
sieve[0],sieve[1]=False,False
for x in xrange(2, int(len(sieve) ** 0.5) + 1):
    if sieve[x]: mark(sieve, x)


def rev(n):
  s=0
  while n>0:
    s=s*10+n%10
    n/=10
  return s

def check(n):
  flag=1
  while n>0:
    if sieve[n]:
      n/=10
    else:
      flag=0
      break
  return flag==1

ctr=0
i=11
s=0
while ctr!=11:
  if check(i) and check(rev(i)):
    print i
    s+=i
    ctr+=1
  i+=1

print s

lww=raw_input()

1 个答案:

答案 0 :(得分:5)

您的算法不正确。您正在查找素数p,使p从右到左可截断,reverse(p)从右到左可截断。

然而,问题是要求您找到素数p,使p从右到左可截断,p从左到右可截断。 p从左到右的可执行性不等于reverse(p)从右到左的可截断性。

考虑问题中给出的数字3797 - 它在两个方向都是可截断的(所以你的代码应该捕获它),但它的反向7973不能从右到左截断,所以你的代码拒绝它。这应该会让你失望。

您需要摆脱reverse(因为这里没有用处),而是修改您的检查代码以截断两个方向。


你得到一个IndexError,因为你的筛子用完了 - 你的代码正确地计算出只有5个p少于100万的素数,这样p就是可截断的权利 - left和reverse(p)从右到左是可截断的。由于那时你没有突破循环(从ctr < 11开始),你的代码会尝试访问sieve[len(sieve)],然后点击IndexError


另外 - 这与你的问题没有关系 - 我认为你来自C背景或类似的东西。您的代码有点难以阅读,因为它不符合标准的Python样式约定。一旦你自己解决了这个问题(本着Project Euler的精神),请查看this gist我对你的实现的更正1.)使其正常工作;和2.)更接近标准的Pythonic风格。