项目Euler 36 Double-base Palindrome Python 3

时间:2015-08-14 12:37:50

标签: python python-3.x math

我正在尝试解决这个问题并且它无法正常工作(python 3)

十进制数,585 = 10010010012(二进制),在两个碱基中都是回文。 求出所有数字的总和,小于一百万,在基数10和基数2中是回文。 (请注意,任何一个基数中的回文数字可能不包括前导零。)

https://projecteuler.net/problem=36

def isPal(number):
##    if (len(number)<2):
##        return True
##    else:
##        return (number[0] == number[-1]) and isPal(number[1:-1])
    return(number == number[::-1])

total = 0
## generating palindromes, by increasing right side  y one and then mirroring to left
import math
digits = 2
number = [0]*digits
while(True):
    if (number == [9]*digits):
        digits+=1
        if (digits == 7):  # "under 1 million"
            break          # done with while(True) because else the digits +=1 would be at bottom
        number = [0]*digits
    number[-1] += 1
# number rolling over
    if (number[-1] == 10): 
        number[-2]+=1           
        number[-1]=1 
        for i in range(2,math.floor(digits/2)+1):         
            if (number[-i] == 10):          
                number[-(i+1)]+=1           
                number[-i]=0                
# mirroring image
    for j in range(1,math.floor(digits/2)+1):
        number[j-1] = number[-j]
    intNumber = 0
    for k in range(len(number)):
        intNumber += number[k]*(10**k)
    if isPal("{0:b}".format(intNumber)):
        total += intNumber
        print("      ",intNumber)
        print("{0:b}".format(intNumber))
print(total)

给出的答案是872162,这是错误的

请帮忙

2 个答案:

答案 0 :(得分:2)

嗯......这是一个非常有趣的方法。我喜欢你的想法!但是你的实现有点难以阅读!

无论如何要解决你的问题:错误是你没有检查1到1000000范围内的所有回文!即你错过了特殊情况&#34; 1位数的回文(1到9)!所以你错过了数字1,3,5,7和9(对应于1,11,101,111,1001)。

现在我的答案的友好建议部分:不要重新发明轮子!如果您正在实现自己的整数数组表示,那么您可能已经过了复杂的事情!相反,对于像这样的简短数学问题,将英语直接翻译成代码,然后优化:

total = 0
for i in range(1,1000000):
    if isDecPalindrome(i) and isBinPalindrome(i):
        total+=i
print(total)

此代码易于阅读并组织您的想法!现在,您所要做的就是实施isDecPalindromeisBinPalindrome

现在你可能会说,&#34;但是,迈克尔!在我的代码中,我只是通过我知道的东西进行了迭代!&#34;真的够了。但我们可以轻松修改此代码以包含该想法!

total = 0
for decPalindrome in decPalindromeGen(1,1000000):
    if isBinPalindrome(decPalindrome):
        total += decPalindrome 
print(total)

现在我们又有了一个组织良好的模板&#34;为我们的解决方案对于第一次阅读此代码的人来说,很容易理解我们在做什么!通过将代码分成1个函数1生成器和一个主循环,编码器让您的生活更轻松!

如果您不熟悉生成器,decPalindromeGen的一个可能定义是:

def decPalindromeGen(l,u):
    for i in range(l,u):
        if isDecPalindrome(i):
            yield i

其中isDecPalindrome是您定义的某个函数,用于检测输入是否为Base 10中的回文。

希望这有启发性:)

编辑:澄清我提供的decPalindromeGen的定义并不比我在没有生成器的第一个例子中所做的更好。它只是为了展示你应该如何拆分代码。为了更有效的算法,请调整decPalindromeGen以更智能地生成回文。

答案 1 :(得分:0)

我将如何做到这一点

def isPal(number):
    number = str(number)
    return (number == number[::-1])
def isBinPal(number):
     number = bin(number)[2:] # bin() returns a string in binary starting with "0b", so we drop the first two characters
    return (number == number[::-1])
sum(x for x in range(1000000) if isPal(x) and isBinPal(x))

查找像bin这样的内置函数将数字转换为二进制将为您节​​省很多麻烦。还知道一些像发电机这样的语言功能会派上用场:)