Egyptian Fractions
June 4, 2013
The largest unit fraction that will fit a given ratio n ÷ d is ⌈ d / n ⌉. Given that, the needed function is simple:
(define (egypt n d)
(let loop ((n n) (d d) (xs (list)))
(if (= n 1) (reverse (cons d xs))
(let* ((x (ceiling (/ d n))) (y (- (/ n d) (/ x)))
(n (numerator y)) (d (denominator y)))
(loop n d (cons x xs))))))
We return the fraction as a list of denominators in ascending order. Here are some examples:
> (egypt 5 6)
(2 3)
> (egypt 7 15)
(3 8 120)
> (egypt 5 121)
(25 757 763309 873960180913 1527612795642093418846225)
You can run the program at http://programmingpraxis.codepad.org/eopIofz7. If you are interested, the study of Egyptian fractions is a fascinating topic; let Google be your guide.
[…] today’s Programming Praxis exercise, our goal is to convert a given fraction to a sum of fractions with […]
My Haskell solution (see http://bonsaicode.wordpress.com/2013/06/04/programming-praxis-egyptian-fractions/ for a version with comments):
here’s my general idea.
while numerator > 1:
subtract the largest factor that’s smaller than the numerator; distribute.
if no such factor:
multiply top and bottom by the smallest value that will put the numerator greater than the smallest factor bigger than it.
for example:
7/15 = (2+5)/15 = 1/3 +2/15 = 1/3 +4/30 = 1/3 +1/10 +1/30
25/37 = 50/(2*37) = (37+13)/(2*37) = 1/2 +13/(2*37) = 1/2 +1/37 +11/(2*37) = 1/2 +1/37 +44/(2*4*37) = 1/2 +1/37 +1/8 +7/(2*4*37)
= 1/2 +1/37 +1/8 +1/74 +3/(2*4*37) = 1/2 +1/37 +1/8 +1/74 +1/148 +1/296.
http://pastebin.com/y9KgqXs1
phil’s program loops indefinitely with inputs of 2/4 and 6/8 (perhaps others.) Maybe it needs to reduce fraction to lowest terms before proceeding.
okay thank you david. i tried to fix the program but there seems to be too many road blocks preventing this algorithm form working. currently
31/466 can’t be done.
Clojure solution for a pairing algorithm. Represent x/y as a list of x copies of the fraction 1/y. Reduce the list each step by looking for pairs with the same denominator. Replace each pair with 2/y (when y is even) or 2/(y+1) + 2/(y(y+1)) when y is odd. In each case, the 2 can be factored out, so the numerator will still be 1. The algorithm halts when there are no more equal denominators in the list.
The Egyptians probably used the pair reduction method because they have a lot of ways in which they would reduce a fraction 2/n where n is odd. but they employed various heuristics to keep the denominators small when n is odd. So this version is also a pair reduction, but uses a lookup table for small odd denominators that looks up the fractions that were used on the Rhind Papyrus. For denominators greater than 101, the identity 1/n + 1/n = 2/(n+1) + 2/(n(n+1) is used.
There is a binary method which takes advantage of the fact that a non-repeating fraction in binary notation is already a sum of unit fractions (e.g. 5/16 = 0.0101 = 1/16 + 1/4, so the method splits a fraction x/y into a sum of inverse powers of two and a remainder portion that is also inverse powers of two multiplied by 1/y. See http://www.ics.uci.edu/~eppstein/numth/egypt/binary.html. Cook thing is that the number of terms is bounded by log(x) + log(y) and denominator is no larger than y^2.
[…] This post presents C# solutions to a coin change problem as described in https://programmingpraxis.com/2013/06/04/egyptian-fractions. […]