圆形素数计划Euler#35

时间:2019-04-13 10:37:24

标签: python python-3.x permutation primes

这是我要解决的问题。

  

数字197被称为圆质数,因为   数字197、971和719本身就是质数。

     

100以下有13个素数:2、3、5、7、11、13、17、31,   37、71、73、79和97。

     

一百万个以下的素数有多少?

这是我的尝试。我首先将所有低于1000000的素数放在称为素数的列表中,然后计算所有可能的排列并将这些排列存储在列表中。然后我检查了这些排列是否是质数。

import math
def isPrime(num):
    flag = 1
    root = int(math.sqrt(num) + 1)
    for i in range (2,root+1):
        if num%i == 0:
            flag = 0
            break
        else:
            flag = 1
    if flag == 1:
        return True
    else:
        return False

primes = [#list of all primes below 1000000]

def permutations(word):
    if len(word) == 1:
        return [word]
    char = word[0]
    perms = permutations(word[1:])
    result = []
    for perm in perms:
        for i in range (len(perm)+1):
            result.append(perm[i:] + char + perm[:i])
    return result

count = 0
for i in primes:
    to_be_tested = permutations(str(i))
    count_to_be_fulfilled = len(to_be_tested)
    new_count = 0
    for j in to_be_tested:
        if isPrime(int(j)):
            new_count += 1
    if new_count == count_to_be_fulfilled:
        count += 1
print(count)

我得到了答案22,根据欧拉计划,这是错误的。我不知道答案,因为我想自己解决这个问题,也不想作弊。请告诉我我在做错什么。

1 个答案:

答案 0 :(得分:0)

解决方案

我将发布完整的解决方案,因为在Project Euler's about部分中:

  

我学到了很多解决问题的方法XXX,可以发表我的文章了吗   解决方案在其他地方?

     

您似乎已经回答了自己的问题   题。完全没有那个“啊哈!”当你   终于解决了您已经解决了一段时间的问题。   通常是出于最好的意图,希望分享我们的   洞察力,以便其他人也可以享受这一刻。可悲的是,   对于您的读者而言,情况并非如此。真正的学习是积极的   过程,看看它是如何完成的   发现的顿悟。请不要否认别人有什么   珍视自己。

不过,我会给您一些提示。

数据结构

正如我在评论中提到的那样,使用集合可以极大地提高程序的性能,因为访问其中的数据确实非常快(您可以通过搜索名为 hashing 的技术来检查原因)如果您不知道)。准确地说,列表的性能为O(N),而集合的性能约为O(1)

轮换与排列

在问题陈述中,您需要计算数字的旋转。正如@ottomeister指出的那样,您应该真正检查程序是否正在执行问题声明所期望的工作。当前,调用permutations("197")将返回以下列表-['791', '917', '179', '971', '719', '197']-而问题期望结果为['197', '971', '719']。而不是创建排列,您应该计算旋转,例如,可以通过将每个数字向左移动(环绕)直到返回初始数字(可以如果您真的喜欢的话,可以制作一个类似的递归算法。

主要检查

您当前正在通过执行循环来检查每个数字是否为素数,该循环检查数字N是否可被所有sqrt(N)整除。正如您所注意到的,这对于许多数字来说是相当慢的,并且有更好的方法来检查数字是否为质数。在您的方案中,理想的解决方案是简单地执行N in primes,因为您已经生成了素数,如果使用集而不是列表,则它们将是O(1)。另外,您可以查看primality tests(尤其是启发式和概率测试)

最后

我通常建议先测试自己的解决方案,然后您很容易发现您的permutations函数根本达不到问题陈述的预期结果。我建议将事情进一步分解为较小的功能,例如,您可以使用与rotations(number)类似的permutations函数,也许可以使用is_circular(number)函数来检查给定的数字是否满足问题要求,并且{ {1}}函数,用于计算和计算循环号。如果您同时注释所有内容,则将使调试工作变得更加容易,并且您将能够确认一切都按预期进行了:)