简体   繁体   English

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

[英]Palindromic numbers divisible by any given number

I have the following problem to solve: The numbers 545, 5995 and 15151 are the three smallest palindromes divisible by 109. There are nine palindromes less than 100000 which are divisible by 109. 我要解决以下问题:数字545、5995和15151是可被109整除的三个最小回文。有九个小于100000的回文可被109整除。

How many palindromes less than 10**32 are divisible by 10000019 ? 多少个小于10 ** 32的回文可被10000019整除?

So my code is shown below. 所以我的代码如下所示。 In theory my code will work, but to count all the way from 0 to 10**32 would take my computer literally YEARS. 从理论上讲,我的代码可以运行,但是从0到10 ** 32的所有数字都将占用我的计算机实际年份。

Is there anyway to improve this code? 无论如何,有没有改进此代码?

Python code: 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)

The problem is presented as Project Euler 655 该问题显示为Euler 655项目

You are getting all palindromes between 0 and 10**32 then filtering using divisibility. 您得到的所有回文数在0到10**32之间,然后使用除数进行过滤。 But you can do it the other way around also. 但是您也可以采用其他方法。 Just find the multiples of 10000019 that are less than 10**32 then check if each multiple is a palindrome. 只需找到小于10**3210000019倍数,然后检查每个倍数是否是回文。

This way you can avoid checking palindromes for numbers that are not required. 这样,您可以避免检查回文中是否存在不需要的数字。

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

Well, you just need to check for numbers divisible by your divisor, so why check numbers before that, and while incrementing, why not just increment the divisor amount? 好吧,您只需要检查除数可整除的数字,那么为什么要在此之前检查数字,并在递增时为何不仅仅增加除数呢?

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

This approach still takes a lot of time, and I'd recommend finding a better method. 这种方法仍然需要很多时间,我建议您找到一种更好的方法。

Given that MathJax doesn't work here it's gonna be tough to present my solution. 鉴于MathJax在这里不起作用,要介绍我的解决方案会很困难。

When you look at a number, eg. 当您查看数字时,例如 1991, you can write this as 1000*1+100*9+10*9+1*1. 1991年,您可以将其写为1000 * 1 + 100 * 9 + 10 * 9 + 1 * 1。 If you look at the remainder when dividing by 19 we have that: 如果看除以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. (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。

Therefore 19 doesn't divide 1991 因此19不除1991

For a palindrome, abcba , we can use this property of modular arithmetic to see that 19 divides abcba if and only if: 对于回文字母abcba ,我们可以使用模块化算术的此属性来查看,当且仅当以下条件为19除以abcba

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

Because 因为

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

By using this method we can cut the number of iterations down to the square root of the max value. 通过使用这种方法,我们可以将迭代次数减少到最大值的平方根。 A routine for calculating the sum of ever palindrome less than 10**10 that is divisible by 109 will look some thing like this. 用于计算回文总和小于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)

Running the calculation for every palindrome less than 10**32, still requires 10**16 iterations, so it's not efficient enough for your problem, it's however better than previous answers (requiring about 10**24 iterations). 为每个小于10 ** 32的回文运行计算,仍然需要进行10 ** 16次迭代,因此对于您的问题而言效率不高,但是它比以前的答案要好(大约需要10 ** 24次迭代)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 找到一组数字的最大子集,使得任何2个数字的总和不能被给定数字整除 - Find the largest subset of a set of numbers such that the sum of any 2 numbers is not divisible by a given number 如何打印范围内的数字但排除给定可整除数字的数字 - How to print numbers from range but exclude a number by a given divisible number 从 0 到给定数字范围内的所有数字的总和,这些数字可以被 7 整除 - Sum of all numbers in range from 0 to a given number that are divisible with 7 如何从范围生成器中打印出不能被给定列表中的任何数字整除的数字 - How to print out numbers from a range generator that are not divisible by any numbers in a given list 查找数字是否可被输入数字整除 - find if a number divisible by the input numbers 如何从给定范围计算一个不能被数组的任何元素整除的数字? - How do I count from a given range a number that is not divisible by any element of the array? python中的回文数 - palindromic numbers in python 如何找到可被给定范围内的数字整除的数字? - how to find number that's divisible by a number in a given range? 使用Python中的逻辑运算符获取可被给定除数整除的数字 - Get numbers divisible by a given divisor using logical operators in Python 连续数可被质数除以帕斯卡三角形的数字数 - Number of numbers divisible by a prime number in a row to pascal triangle
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM