【问题标题】:Issue with Project Euler #37Project Euler #37 的问题
【发布时间】:2020-03-17 01:03:21
【问题描述】:

我尝试了几种方法来解决 Project Euler #37,并编写了代码(我对其进行了背景检查,它似乎工作得很好)但是在问题中它指出只有 11 个可能的答案我需要总结一下,但我得到了 30。 问题是:

数字 3797 有一个有趣的特性。作为素数本身,它是 可以从左到右连续删除数字,并保持 每个阶段的素数:3797、797、97 和 7。类似地,我们可以从 从右到左:3797、379、37 和 3。

找出仅有的 11 个可以截断的素数之和 从左到右,从右到左。

注意:2、3、5 和 7 不被视为可截断的素数。

因此,对于每个素数,我遍历其数字的 len 范围并将它们连接起来进行检查,然后检查该数字是否也是素数,我向前和向后执行此操作。如果它们都是素数,我会附加到结果(原始数字)并总结。

代码如下:

def trunc_primes():
    it_range = range(9, 10000)
    primes = [i for i in it_range if all((i%d)!=0 for d in range(2, i//2))]
    results = []
    counter=0

    for prime in primes:
        splitted = list(str(prime))
        forwards = splitted.copy()
        backwards = splitted[::-1]

        forward_range = range(len(forwards))
        prime_check_dict = {}
        for i in forward_range: prime_check_dict[i]=False

        for fr in forward_range:
            forward = int(''.join(forwards[0+fr:]))
            backward = int(''.join(backwards[0+fr:][::-1])) # reverse back the reversed list

            if all((forward%d)!=0 for d in range(2, forward//2)):
                if all((backward%e)!=0 for e in range(2, backward//2)):
                    prime_check_dict[fr]=True 

        if all(prime_check_dict[i]==True for i in prime_check_dict):
            results.append(prime)
            counter+=1


#here is also some sample background work at the second for loop:

#original:  ['9', '9', '7', '3']
#forward:  9973
#backward:  9973
#original:  ['9', '9', '7', '3']
#forward:  973
#backward:  997
#original:  ['9', '9', '7', '3']
#forward:  73
#backward:  99
#original:  ['9', '9', '7', '3']
#forward:  3
#backward:  9

也许我遗漏了一个应该很明显的小细节,或者我误解了问题的背景

【问题讨论】:

    标签: python performance debugging


    【解决方案1】:

    主要问题是你程序中的测试不正确,因为它接受了显然不是素数的 1 和 4:

    all((i%d)!=0 for d in range(2, i//2))]
    

    在我看来,另一个问题是你停在 9999。如果有 5 位数的解,这个限制要么太低,要么如果你早先找到所有 11 个解,这个限制太高。 (后者恰好是真的。)

    测试素数时除法的上限是 sqrt(N)。使用N//2 作为上限不是错误,但对于较大的数字来说效率很低。

    我对提高速度的主要建议是利用已经生成了一组较小的素数。例如,在测试 3797 时,您不必对派生的较小数字 379、37 和 3 执行测试。只需检查它们是否(或不)存在于已生成的素数集中到 3797。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-17
      • 2010-09-27
      • 1970-01-01
      • 2011-10-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多