[Python / Project Euler]问题41

时间:2010-07-31 21:12:34

标签: python

我正在尝试解决problem 41,但我不知道为什么我的代码会停在987654319:

def IsPandigital(No):
 a = sorted(str(No))
 for i in range(1,10):
  if a[i - 1] != str(i):
   return False
 return True
def IsPrime(No):
 i = 2
 while i < No:
  if No % i == 0:
   return False
  i += 1
 return True
i = 987654321
while i > 0:
 print i
 raw_input()
 if IsPrime(i) == True and IsPandigital(i) == True:
  print i
  break
 i -= 1
print i
print "EOP"
raw_input()

P.S:我知道我应该从799999999开始,因为:

  

GergS:每9位数和8位数的数字数字可以被3整除。

3 个答案:

答案 0 :(得分:10)

您的IsPrime功能非常慢。它很快就计算出987654321可以被3分割,而987654320可以被2分割。但是,987654319是素数并且需要非常长的时间来检查所有除数,所以看起来好像它已经停止了。

问题需要的不仅仅是简单的计算,就像你所做的那样。计算素数是一个缓慢的过程,因此您应该对其进行优化,例如:

  • IsPandigital之前测试IsPrime
  • 更好的是,只创建一个列表 pandigital数字并成为素数 测试。提示:pandigital数字为:[987654321,987654312,987654231,987654213,...]
  • 你不必制作循环while i < No - 这就足够了 sqrt(No)
  • 以数字0,2,4,5,6或8结尾的数字永远不会是素数
  • 另一种选择可能是计算所有n位数的素数,然后选择最大的数字数字。

您的其他问题:

  • 您正在计算最大的 9位 pandigital prime。问题是“最大的 n位 pandigital prime”,所以你应该可以根据参数计算任何长度
  • 你不应该像你写的那样从799999999开始。你应该简单地跳过n = 3,n = 5,n = 6,n = 8和n = 9的计算,因为这些都不是素数。

答案 1 :(得分:1)

查找素数的例程比pandigital要长得多,因此切换它们的运行顺序。所以它应该是:

if IsPandigital(i) == True and IsPrime(i) == True:

答案 2 :(得分:1)

尝试使用itertools.permutations生成所有泛数字数字,然后检查它们是否为素数。它生成传递的字符串的所有排列。

E.g。

itertools.permutations('9876543210')

您可以缩小搜索范围,如上所述,9876543210就是一个例子。