Saturday, October 18, 2008

Project Euler Problem 33 Curious Fractions

[root@www ~]# python thirtythree.py
[16, 64]
[19, 95]
[26, 65]
[49, 98]
There were 4 curious fractions.
Started at: Sat Oct 18 21:53:18 2008 Ended at: Sat Oct 18 21:53:18 2008
[root@www ~]# cat thirtythree.py
from __future__ import division
"""
<+ 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()

# The fraction 49/98 is a curious fraction,
# as an inexperienced mathematician in attempting to simplify it
# may incorrectly believe that 49/98 = 4/8,

def shortcut(numerator, denominator, n,m):
"""
Tests for a non-zero digit which is in both the two-digit numerator
and the two-digit denominator

>>> shortcut(49, 98, 1,0)
True

>>> shortcut(48,98, 1,0)
False

>>> shortcut(40,80, 1,1)
False

>>> shortcut(77,77,1,1)
False

>>> shortcut(9,99,0,0)
False

>>> shortcut(9,99,0,1)
False

>>> shortcut(11,111, 1,1)
False

"""
if numerator < 10 or numerator > 99 or denominator < 10 or denominator > 99:
return False
if numerator >= denominator:
return False
if str(numerator)[n] == str(denominator)[m]:
if str(numerator)[n] == '0':
return False
else:
return True
else:
return False

def flip(n):
"""
Turns a zero into a one and a one into a zero

>>> flip(0)
1

>>> flip(1)
0

"""

return (n + 1) % 2

def testShortcut(numerator, denominator,n,m):
"""
Tests to see whether applying a shortcut produces
an incorrect answer.

First make sure that Python's division is working properly
>>> 1/2
0.5

>>> testShortcut(49,98,1,0)
[49, 98]

>>> testShortcut(49,98,0,1)
False

>>> testShortcut(49,88,0,0)
False

"""
if shortcut(numerator, denominator, n,m):
num = int(str(numerator)[flip(n)])
den = int(str(denominator)[flip(m)])
if den == 0:
return False
if numerator/denominator == num/den:
return [numerator,denominator]
return False

def countCurious():
"""
returns how many curious numbers there are with two digit
numerators and denominators

"""

count = 0
for numerator in range(10,100):
for denominator in range(numerator,100):
for n in range(2):
for m in range(2):
result = testShortcut(numerator, denominator,n,m)
if result:
print result
count += 1
return "There were " + str(count) + " curious fractions."

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

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

No comments: