Python 投影Euler 37可截断素数

Python 投影Euler 37可截断素数,python,python-3.x,Python,Python 3.x,可截断数字的定义如下: 3797这个数字有一个有趣的特性。作为素数本身,可以从左到右连续删除数字,并在每个阶段保持素数:3797、797、97和7。类似地,我们可以从右到左工作:3797、379、37和3 求从左到右和从右到左都可截断的十一个素数之和 注:2、3、5和7不被视为可截断素数 def is_prime(number): """returns True for a prime number, False otherwise.""" factor = 2 whil

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

求从左到右和从右到左都可截断的十一个素数之和

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

def is_prime(number):
    """returns True for a prime number, False otherwise."""
    factor = 2
    while factor * factor <= number:
        if number % factor == 0:
            return False
        factor += 1
    return True


def get_truncatable(n):
    """returns truncatable numbers within range n."""
    for number in range(9, n, 2):
        if is_prime(number):
            check = 0
            for index in range(-1, -len(str(number)), -1):
                less_right = str(number)[:index]
                if not is_prime(int(less_right)):
                    check += 1
            if check == 0:
                for index in range(1, len(str(number))):
                    less_left = str(number)[index:]
                    if not is_prime(int(less_left)):
                        check += 1
                if check == 0:
                    yield number


if __name__ == '__main__':
    print((list(get_truncatable(1000000))))
代码应返回[23、37、53、73、313、317、373、797、3137、3797、739397]或其等价总和:748317

它返回:[11、13、17、23、31、37、53、71、73、113、131、137、173、197、311、313、317、373、797、1373、1997、3137、3797、7331、73331、739397]

正如你所看到的,我的代码中的“31”和所有其他数字一样是可截断的,当我搜索时,我发现代码给出了第一个输出

这种差异究竟来自何方?我错了吗?我说得对吗?

你的is\u prime返回1的真值。您可以将其作为特例添加

def is_prime(number):
    """returns True for a prime number, False otherwise."""
    factor = 2
    while factor * factor <= number:
        if number % factor == 0:
            return False
        # additional speedup here
        factor += 1 + factor % 2
    return number > 1

更有效的方法是生成一组素数作为字符串。然后检查列表中是否有符合截断条件的条目,该条件更容易用子字符串表示:

首先生成最大为1000000的字符串素数。有很多方法可以做到这一点,但埃拉托斯烯的筛子既简单又快速:

R      = 1000000
sieve  = [True]*R
primes = set()
for n in range(2,R+1):
    if sieve[n-1]:
        primes.add(str(n))
        sieve[n*n-1::n] = [False]*len(range(n*n-1,R,n))
然后检查合格的素数:

truncable = []
for p in primes:
    if len(p) == 1: continue
    if all(p[:i] in primes and p[i:] in primes for i in range(1,len(p))):
        truncable.append(int(p))

print(sum(truncable))

1不是质数,因此任何以1开头或结尾的数字都不可左右截断。第一个可截断素数是23,我做了,它运行得很好,谢谢。关于效率,你有什么建议吗?大概需要10秒才能显示出来output@emadboctor继续检查大于2的偶数作为因子是徒劳的,因此只检查2和奇数可以实现约50%的加速。我修改了我的答案以合并它。@emadboctor您也可以尝试作为第一步来查找n下的所有素数,并在is_素数检查中使用此集合,而不是在每次测试中反复进行计算。在相对较小的上界下发现素数的常用方法是