mirror of
https://github.com/jlengrand/project_euler.git
synced 2026-03-10 00:31:21 +00:00
90 lines
2.6 KiB
Python
90 lines
2.6 KiB
Python
#!/usr/bin/env python
|
|
'''
|
|
Created on 10 feb. 2012
|
|
|
|
@author: Julien Lengrand-Lambert
|
|
|
|
DESCRIPTION: Solves problem 41 of Project Euler
|
|
We shall say that an n-digit number is pandigital if it makes use of all the digits 1 to n exactly once. For example, 2143 is a 4-digit pandigital and is also prime.
|
|
|
|
What is the largest n-digit pandigital prime that exists?
|
|
'''
|
|
|
|
val = 123456789 # all numbers to create the biggest pandigital number
|
|
def is_prime(value):
|
|
"""
|
|
Returns True or False depending whether value is prime or not.
|
|
"""
|
|
start = 2
|
|
while (start <= value / 2):
|
|
if value % start == 0 :
|
|
return False
|
|
else :
|
|
start += 1
|
|
return True
|
|
|
|
# I could use a decorator to remove trivial non primes here
|
|
def all_permutations(seq):
|
|
"""permutates a sequence and returns a list of the permutations"""
|
|
if not seq:
|
|
return [seq] # is an empty sequence
|
|
else:
|
|
temp = []
|
|
for k in range(len(seq)):
|
|
part = seq[:k] + seq[k+1:]
|
|
for m in all_permutations(part):
|
|
temp.append(seq[k:k+1] + m)
|
|
return temp
|
|
|
|
def divisible_by_2(val):
|
|
"""
|
|
Returns True if val contains an even number (ex : 998)
|
|
"""
|
|
return ((val % 2) == 0)
|
|
|
|
def divisible_by_5(val):
|
|
"""
|
|
Returns True if any circular permutation of val is divisible by (ex : 907)
|
|
"""
|
|
return (str(5) == str(val)[-1])
|
|
|
|
def divisible_by_3(val):
|
|
"""
|
|
Returns True if any circular permutation of val is divisible by 3 (ex : 12)
|
|
"""
|
|
temp = sum([int(p) for p in str(val)])
|
|
if len(str(temp)) > 1:
|
|
divisible_by_3(temp)
|
|
else:
|
|
return ((temp % 3) == 0)
|
|
|
|
def check_easy_out(pelist):
|
|
"""
|
|
Returns the number of circular primes below max_val
|
|
|
|
TODO : do this while creating all the permutations !
|
|
"""
|
|
pred = list(pelist)
|
|
for p in pelist:
|
|
if p > 11: # my filter does not work for values under 10
|
|
if (divisible_by_2(p) or divisible_by_5(p) or divisible_by_3(p)):
|
|
pred.remove(p)
|
|
return pred
|
|
|
|
def biggest_pandigital():
|
|
"""
|
|
Returns the biggest pandigital prime number
|
|
"""
|
|
for n in range(9): # from 0 to 9 numbers removed of max pand number
|
|
print " n : %d" %(n)
|
|
root = str(val)[:len(str(val)) -n]
|
|
perms = [ int(p) for p in all_permutations(root)]
|
|
perms = check_easy_out(perms)
|
|
perms.sort(reverse=True)
|
|
for p in perms :
|
|
if is_prime(p):
|
|
return p
|
|
|
|
return -1 # problem
|
|
if __name__ == '__main__':
|
|
print "Answer : %d " % (biggest_pandigital()) |