【问题标题】:Project Euler #35 : Reason for the incomplete output in my solutionProject Euler #35:我的解决方案中输出不完整的原因
【发布时间】:2019-07-30 13:57:56
【问题描述】:

Problem 35, Project Euler 我的解决方案的输出停止在一个相当奇怪的点,原因超出了我目前的理解。我已经按照纸上的代码进行了操作,这对我来说似乎是正确的。

prime_list =[]
prime2 = []
prime2_up=[]
##The sieve of eratosthenes##c
def prime_sieve(n):
    prime = [True for i in range(0,n+1)]
    p = 2
    while p*p<=n:
        if prime[p] == True:
            for i in range(p*p,n+1,p):
                prime[i] = False
        p+=1
    for p in range(2,n):
        if prime[p]:
            prime_list.append(p)
##Check whether the given prime is circular or not##
def circular_checker():
    for j in prime_list:
        x = str(j)
        for i in range(0,len(x)):
            x = x[i:len(x)]+x[0:i]
            if int(x) not in prime_list:
                return False
        prime2.append(int(x))
##Function To remove duplicates and sort the list##
def remove_duplicate():
    for k in prime2:
        if k not in prime2_up:
            prime2_up.append(k)
            prime2_up.sort()

prime_sieve(1000)
circular_checker()
remove_duplicate()

print(prime2_up)


我希望输出是一个最大为 1000 的循环素数列表,但该列表突然停在 19 处。

输出: [2、3、5、7、11、31、71]

请说明我的解决方案中的缺陷,并说明相关原因。

编辑 1

感谢@khelwood 和@dollarAkshay 的有用回复。但现在我面临一个过度计数的新问题。 更新后的代码表示的循环素数是121,这确实是错误的。

##updated part, also the exclusion of numbers with digits 2,4,6,8,0 and 5 to reduce runtime##
def circular_checker():
    for j in prime_list:
        x = str(j)
        circular = True
        for i in range(0,len(x)):
            x = x[i:len(x)]+x[0:i]
            if not prime[int(x)] or "2" in x or "4" in x or "6" in x or "8" in x or "0" in x or "5" in x:
                circular = False
                break
        if circular:
            prime2.append(int(x))

prime_sieve(1000000)
circular_checker()
prime2_up.append(2)
prime2_up.append(5)
remove_duplicate()

print(len(prime2_up))

【问题讨论】:

  • 下一个圆形素数应该是什么?
  • 应该有 13, 17 但你问下一个是 79
  • 您可以通过制作一组来删除重复项:prime2_up = list(sorted(set(prime2))),或者更好的是,从一开始就使用一组
  • @khelwood The number, 197, is called a circular prime because all rotations of the digits: 197, 971, and 719, are themselves prime.
  • 您的 circular_checker 在循环中间有一个 return false 。这将退出您的整个循环,因此此后将不再检查素数。

标签: python python-3.x math output


【解决方案1】:

您的 circular_checker 在循环中间有一个 return false 。这将退出您的整个循环,因此此后将不再检查素数。

不要在循环中途返回来解决这个问题。

def circular_checker():
    for j in prime_list:
        x = str(j)
        circular = True
        for i in range(0,len(x)):
            x = x[i:len(x)]+x[0:i]
            if int(x) not in prime_list:
                circular = False
                break
        if circular:
            prime2.append(int(x))

【讨论】:

  • @MarkMeyer 938 也是一种可能的轮换方式
  • @YourAverageEuler 实际上都不是圆形素数,因为定义是 所有 旋转都是素数。小于 1000000 的圆素数数量少得惊人。
【解决方案2】:

你的程序不是停在 71 而是停在 19。

基本上前几个素数:2, 3, 5, 7, 11, 13, 17 都是圆素数。因此,在circular_checker() 函数中,当它检查19 时,它会尝试检查91 是否在列表中。由于91 不是素数,它返回False 并退出函数。

我相信您想要做的是跳出内部 for 循环而不是从函数返回。

这是循环函数的正确实现:

def circular_checker():
    for j in prime_list:
        x = str(j)
        isCircular = True                     #This line was changed
        for i in range(0, len(x)):
            x = x[i:len(x)]+x[0:i]
            if int(x) not in prime_list:
                isCircular = False            #This line was changed
                break                         #This line was changed
        if isCircular:                        #This line was changed
            prime2.append(int(x))

【讨论】:

  • 这应该是公认的答案,因为它对问题给出了最完整和正确的解释,但 khelwood 的答案也是正确的。
【解决方案3】:

一种更有效的方法是生成一组素数作为字符串,并检查列表中每个条目是否存在旋转数字。

首先生成高达 1000000 的素数。有很多方法可以做到这一点,但 Eratosthenes 的筛子既简单又快速:

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))

然后检查所有旋转也出现在素数列表中的素数:

circular = []
for p in primes:
    if all(p[i:]+p[:i] in primes for i in range(len(p))):
        circular.append(p)

print(len(circular)) # number of circular primes

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-30
    • 2013-07-30
    • 1970-01-01
    • 1970-01-01
    • 2011-03-03
    • 1970-01-01
    • 2023-03-15
    相关资源
    最近更新 更多