I've recently started teaching myself Python. I'm trying to work through the Project Euler problems. Problem 32 is:
Here's my code, which gives the correct solution (45228):
list = []
new_list = []
# Create list of 9 digit pandigital numbers
for a in range(1, 100):
for b in range(100, 10000):
c = a * b
num = len(str(c)) + len(str(a)) + len(str(b))
if num == 9:
xxx = str(c) + str(b) + str(a)
if "1" in xxx and "2" in xxx and "3" in xxx and "4" in xxx and "5" in xxx and "6" in xxx and "7" in xxx and "8" in xxx and "9" in xxx:
list.append(int(str(c)))
# Remove duplicates
for item in list:
if item in new_list:
continue
else:
new_list.append(item)
print(sum(new_list))
The long if statement with the several ands, even to my beginner's eyes, looks clumsy. Without rewriting the whole thing, how can I replace that statement with something more succinct?
I've recently started teaching myself Python. I'm trying to work through the Project Euler problems. Problem 32 is:
Here's my code, which gives the correct solution (45228):
list = []
new_list = []
# Create list of 9 digit pandigital numbers
for a in range(1, 100):
for b in range(100, 10000):
c = a * b
num = len(str(c)) + len(str(a)) + len(str(b))
if num == 9:
xxx = str(c) + str(b) + str(a)
if "1" in xxx and "2" in xxx and "3" in xxx and "4" in xxx and "5" in xxx and "6" in xxx and "7" in xxx and "8" in xxx and "9" in xxx:
list.append(int(str(c)))
# Remove duplicates
for item in list:
if item in new_list:
continue
else:
new_list.append(item)
print(sum(new_list))
The long if statement with the several ands, even to my beginner's eyes, looks clumsy. Without rewriting the whole thing, how can I replace that statement with something more succinct?
Share Improve this question asked Feb 17 at 13:29 Peter4075Peter4075 1111 silver badge4 bronze badges 2- There are not a lot of ways to check if each digit from 1 to 9 are all inside of a string that has to be 9 characters long... What do you expect? – S.Comeau Commented Feb 17 at 13:38
- @S.Comeau - To paraphrase Inspector Clouseau, I expect everything and I expect nothing :-) – Peter4075 Commented Feb 17 at 14:12
2 Answers
Reset to default 1By issubset
:
if set('123456789').issubset(xxx):
Or by sorting (this way you don't need your length check):
if sorted(xxx) == [*'123456789']:
(I would've written list('123456789')
but had to resort to [*...]
because you overwrote list
. Better don't do that.)
Or by counting the different nonzero digits:
if len(set(xxx) - {'0'}) == 9:
My own solution was:
print(sum({
a * b
for a in range(100)
for b in range(a, 10000)
if sorted(f'{a}{b}{a*b}') == list('123456789')
}))
Equivalent short line is:
if all(el in xxx for el in map(str, range(1,10))):
Explanation:
all
is a function that replaces chain of and
s. You give it an iterable to check if all objects are true.
map(str, range(1,10))
takes numbers 1-9 and converts them to equivalent strings ("1", "2",... etc.) - in this case, it can be simplified to '123456789'
It then makes a generator expression for all the numbers and checks if all of the generated values are in xxx
.