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