回文数可被任何给定数整除

时间:2019-04-20 10:34:50

标签: python

我要解决以下问题: 数字545、5995和15151是可被109整除的三个最小回文。有九个小于100000的回文可被109整除。

多少个小于10 ** 32的回文可以被10000019整除?

所以我的代码如下所示。 从理论上讲,我的代码可以工作,但是从0到10 ** 32的所有数字都将实际占用我的计算机。

反正还有改进此代码的地方吗?

Python代码:

listPalindroms=[]
for i in range (0,10**32):
    strI = str(i)
    printTrue = 1
    if len(strI) == 1:
        listPalindroms.append(i)
    else:
        if len(strI)%2 ==0:
            FinalVal = int(len(strI)/2)
            for count in range (0,FinalVal):
                if strI[count]!=strI[-count-1]:
                    printTrue = 0
            if printTrue==1: listPalindroms.append(i)
        else:
            FinalVal = int(round(len(strI)/2))-1
            for count in range (0,FinalVal):
                if strI[count]!=strI[-count-1]:
                    printTrue = 0
            if printTrue ==1: listPalindroms.append(i)

i=0
for item in listPalindroms:
    if item%10000019 ==0:
        i = i + 1
print (i)

问题显示为Project Euler 655

3 个答案:

答案 0 :(得分:2)

您将得到0到10**32之间的所有回文,然后使用除数进行过滤。但是您也可以采用其他方法。只要找到10000019的倍数小于10**32,然后检查每个倍数是否是回文。

这样,您可以避免检查回文中是否存在不需要的数字。

i = 1
number = 10000019
list_palindromes = []
element = number * i
while element < (10**32):
    e = str(element)
    for j in range(len(e)):
        if e[j] != e[len(e)-j-1]:
            break
        if len(e)-1 == j:
            list_palindromes.append(e)
            print(e)
    i += 1
    element = number * i

答案 1 :(得分:1)

鉴于MathJax在这里不起作用,提出我的解决方案会很困难。

当您查看数字时,例如1991年,您可以将其写为1000 * 1 + 100 * 9 + 10 * 9 + 1 * 1。 如果将除以19的余数看一下,我们会得到:

(1000 * 1 + 100 * 9 + 10 * 9 + 1 * 1)%19 =((1000%19)* 1 +(100%19)* 9 +(10%19)* 9 +(1 %19)* 1)%19 =(12 * 1 + 5 * 9 + 10 * 9 + 1 * 1)%19 = 10。

因此19不会除1991

对于回文, abcba ,我们可以使用模块化算术的此属性来查看19除 abcba 时,且仅当:

(7 * a + 3 * b + 5 * c)%19 = 0

因为

(10000 * a + 1000 * b + 100 * c + 10 * b + a)%19 =(10001 * a + 1010 * b + 100 * c)%19 =(10001 * a%19 + 1010 * b%19 + 100 * c%19)%19 =(7 * a + 3 * b + 5 * c)%19

通过使用这种方法,我们可以将迭代次数减少到最大值的平方根。计算回文总和小于10 ** 10并被109整除的例程将看起来像这样。

maxValue = 10**5
divisor = 109

moduli = []
for i in range(0,33):
    moduli.append((10**i)%divisor)

def test(n,div):
    n = str(n)
    sum_odd = 0
    sum_even = 0
    for i in range(len(n)):
        sum_even = sum_even + int(n[i])*(moduli[i]+moduli[2*len(n)-i-1])
        if i != len(n)-1:
            sum_odd = sum_odd + int(n[i])*(moduli[i]+moduli[2*len(n)-i-2])
        else:
            sum_odd = sum_odd + int(n[i])*(moduli[i])
    if sum_odd%div==0 and sum_even%div==0:
        return 2
    if sum_odd%div==0 or sum_even%div==0:
        return 1
    else:
        return 0

# The sum starts at -1 because 0 is counted twice
sum = -1
for a in range(maxValue):
    sum = sum + test(a,divisor)
print(sum)

为每个小于10 ** 32的回文运行计算,仍然需要进行10 ** 16次迭代,因此对于您的问题而言效率不高,但是它比以前的答案要好(需要10 ** 24次迭代)。 / p>

答案 2 :(得分:0)

那么,您只需要检查除数可整除的数字,那么为什么要在此之前检查数字,并在递增时为何不增加除数呢?

def is_palin(num):
    num_str = str(num)
    for index in range(len(num_str)/2):
        if num_str[index]==num_str[len(num_str)-1-index]:
            continue
        return False
    return True

def multiple(divisor, end):
    count=0
    index = divisor*2
    while index<end:
        if is_palin(index):
            count+=1
        index+=divisor

    return count

if __name__=="__main__":
    print(multiple(109, 100000))
    # print(multiple(10000019, 10**32))

这种方法仍然需要很多时间,我建议您找到一种更好的方法。