Reputation: 31
I have been trying to find the answer to problem #4 in Project Euler in Python but I really can´t seem to find the problem in my code. Here is the question:
A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99. Find the largest palindrome made from the product of two 3-digit numbers.
And here is my code:
nums = list(range(10000, 998001))
pals = []
def palindrome(a):
if str(a) == reversed(str(a)):
pals.append(a)
for every in nums:
palindrome(every)
Upvotes: 1
Views: 123
Reputation: 882626
For a start, try printing out the string and its supposed reversal - you'll find they're not as you expect. A more sensible way of getting the string reversal of s
is with s[::-1]
.
Then you need to realise that you're checking every number in that range of yours, 10000..998000
(noticing I've left out 998001
there since Python ranges are exclusive at the end). Not all of those numbers will be a product of two 3-digit numbers. Of course, it may be that was going to be your next step once you'd got all the palindromes, in which case feel free to ignore this paragraph (other than fixing the range, of course).
As an aside, I probably wouldn't wrap that range in a list. If you're using Python 2, it's already a list and, for Python 3, it's probably better to leave it as a lazy iterator so as not to waste memory.
And, as a final aside, I probably wouldn't do it this way since I prefer readable code but those who demand "Pythonic" solutions may like to look at something like:
print(max((i*j
for i in range(100,1000)
for j in range(100,1000)
if str(i*j) == str(i*j)[::-1]
)))
though of course true Python aficionados will want that on a single line :-) I've just split it for readability.
Upvotes: 3
Reputation: 4824
Let me start with what everyone else pointed out: reversed(s)
is not the same as s[::-1]
.
Everyone else wanted you to use s[::-1]
instead of reversed()
. Sure, that suggestion is scrutable and idiomatic. But why limit yourself! This is Python, after all.
from itertools import combinations, ifilter, imap, starmap
from operator import eq, mul
def is_palindrome(integer):
"""Returns a True if an input integer's digits are palindromic, False otherwise."""
string = str(integer)
return all(imap(eq, iter(string), reversed(string)))
def largest_palindrome_product(n_digits=3):
"""Solves Project Euler #4"""
all_n_digit_numbers = xrange(10**(n_digits)-1, 10**(n_digits-1), -1)
palindromes = ifilter(is_palindrome,
(starmap(mul, combinations(all_n_digit_numbers, 2)))
)
return max(palindromes)
largest_palindrome_product()
This solution has the valuable feature of retaining the use of reversed()
! For extra inscrutability I tried to use as many functions from itertools
as I could.
Upvotes: 0
Reputation: 1484
Because reversed
returns an iterator
object, you should replace str(a) == reversed(str(a))
with str(a) == str(a)[::-1]
. The [::-1]
qualifier is a string splicing that will reverse the collection.
Upvotes: 0
Reputation: 6719
Python's reversed
returns an iterator
object. So, no one string could be equal to the iterator.
Upvotes: 2