Search code examples
pythonpalindrome

How to avoid lists when analyzing order for palindromes?


Just want to apologize in advance for the general coding and logic gore you might encounter while reading this. I recently discovered Project Euler and thought it was fun. I've made it a point to not only find the answer, but make a generic function that could find the answer for any similar case given the appropriate input. For instance, problem number 4, involving palindromes, which can be seen here: https://projecteuler.net/problem=4

Essentially what I did was found a way to multiply every possible combination of numbers given a number of digits, n, then found products that were palindromes. However, anything above 3 digits just takes way too long to process. I believe this is because I used the list() function to take advantage of indexing to determine whether the product was a palindrome. Is there another way to do something of this nature? I feel like this is shoving a square through a circular hole.

Here's the function in question.

def palindrome(n):
    number = 0
    for i in range(0,n):
        number = number + 9 * pow(10, i)
    a = pow(10, n - 1) - 1
    b = pow(10, n - 1)
    while a * b < number * number:
        a = a + 1
        b = a
        while b <= number:
            c = a * b
            b = b + 1
            digits = list(str(int(c)))
            lastdigits = digits[::-1]
            numdigits = len(digits)
            middle = int((numdigits - (numdigits % 2)) / 2) - 1
            if numdigits > 1 and digits[:middle + 1] == lastdigits[:middle + 1] and digits[0] == digits[-1] == '9' and numdigits == 2 * n:
                print(c)

Solution

  • "Find the largest palindrome made from the product of two 3-digit numbers."

    3-digit numbers would be anything from 100 - 999. One thing about the largest product is guaranteed: The two operands must be as large as possible.

    Thus, it would make sense to step through a loop starting from the largest number (999) to the smallest (100). We can append palindromes to a list and then later return the largest one.

    When you calculate a product, convert it to a string using str(...). Now, checking for palindromes is easy thanks to python's string splicing. A string is a palindrome if string == string[::-1], where string[::-1] does nothing but return a reversed copy of the original.

    Implementing these strategies, we have:

    def getBiggestPalindrome():
        max_palindrome = -1
        for i in range(999, 99, -1):
            for j in range(999, i - 1, -1):
                prod = i * j
                str_prod = str(prod)
                if str_prod == str_prod[::-1] and prod > max_palindrome: 
                    print(prod)
                    max_palindrome = prod
    
        return max_palindrome
    

    getBiggestPalindrome()

    And, this returns

    >>> getBiggestPalindrome()
    906609
    

    Note that you can use the range function to generate values from start, to end, with step. The iteration stops just before end, meaning the last value would be 100.