Tuesday, October 14, 2008

Project Euler Pandigital Numbers Problem 32

[root@www ~]# python thirtytwo.py
45228
Started at: Tue Oct 14 13:38:21 2008 Ended at: Tue Oct 14 13:38:27 2008
[root@www ~]# cat thirtytwo.py
# -*- coding: utf-8 -*-
"""
<+ MODULE_NAME +>
Project Euler Problem Set
<+ DESCRIPTION +>
Solutions in Python to the problems at http://projecteuler.net

Licensed under the Creative Commons license; see http://creativecommons.org for more details. In short, this means you can freely reuse, modify and distribute this program, also commercially, for as long you provide a proper attribution.

Copyright by Jonathan Mark, jonathanmark.com/aristede.com, jmark@aristede.com

>>> print 881 + 1
882

"""
import time
starttime = time.asctime()


def testExactlyOnce(s,n):
"""
Returns true if a digit appears exactly once in a string
and the string contains no zeroes

>>> testExactlyOnce('11234567890',1)
False

>>> testExactlyOnce('123456789',0)
False

>>> testExactlyOnce('123456789',9)
True

>>> testExactlyOnce('123450',6)
False

"""

s = str(s)
if s.count(str(0)) > 0:
return False
if s.count(str(n)) == 1:
return True
else:
return False


def concatenate(n1,n2):
"""
Multiplies n1 * n2 and concatenates result to n1 and n2

>>> concatenate(186,39)
'186397254'

"""

return str(n1)+ str(n2) + str(n1*n2)

def testBothPandigital(n):
"""
tests whether a five digit number, when split into
numbers of lengths 4,1 and 3,2, produces Pandigital
numbers

>>> testBothPandigital(18639)
7254

"""
tot = 0
if testPandigital(concatenate(int(str(n)[:4]),int(str(n)[4]))):
tot = int(str(n)[:4]) * int(str(n)[4])
if testPandigital(concatenate(int(str(n)[:3]),int(str(n)[3:]))):
tot = int(str(n)[:3]) * int(str(n)[3:])
return tot

def testPandigital(s):
"""
tests whether n1, n2 and n1*n2 cof concatenate(int(str(n)[:4]),int(str(n)[4]):
contain each of the digits
0 - 9 exactly once.

>>> testPandigital('186397254')
True

>>> testPandigital('2323')
False

"""

for i in range(1,10):
if testExactlyOnce(s,i) == False:
return False
return True

def unique100000():
"""
return a range consisting of all numbers less than 100000
which do not contain any zeroes and in which no digit
appears more than one time.

>>> len(unique100000())
15120

"""

numbers = []
for n in range(11111,100000):
unique = True
for i in range(len(str(n))):
if not testExactlyOnce(str(n), int(str(n)[i])):
unique = False
if str(n).count('0') > 0:
unique = False
if unique:
numbers.append(n)
return numbers

final ={}

for n in unique100000():
if testBothPandigital(n) > 1111:
final[testBothPandigital(n)] = 0
print sum(final.keys())


print "Started at: ", starttime, " Ended at: ",time.asctime()

if __name__ == "__main__":
import doctest
doctest.testmod()

No comments: