Greedy algorithm for Egyptian fractions: Difference between revisions

Added link to numberphile video
(Added link to numberphile video)
 
(47 intermediate revisions by 16 users not shown)
Line 1:
{{task}}
 
An &nbsp; [[wp:Egyptian fraction|<u>Egyptian fraction</u>]] &nbsp; is the sum of distinct unit fractions such as:
 
:::: <big><big> <math> \tfrac{1}{2} + \tfrac{1}{3} + \tfrac{1}{16} \,(= \tfrac{43}{48})</math>. </big></big>
 
Each fraction in the expression has a numerator equal to <math>&nbsp; '''1</math>''' &nbsp; (unity) &nbsp; and a denominator that is a positive integer, &nbsp; and all the denominators are distinct &nbsp; (i.e., no repetitions).
 
Fibonacci's &nbsp; [[wp:Greedy algorithm for Egyptian fractions|<u>Greedy algorithm for Egyptian fractions</u>]] &nbsp; expands the fraction &nbsp; <big> <math> \tfrac{x}{y} </math> </big> &nbsp; to be represented by repeatedly performing the replacement
 
:::: <big> <math> \frac{x}{y} = \frac{1}{\lceil y/x\rceil} + \frac{(-y)\!\!\!\!\mod x}{y\lceil y/x\rceil} </math> </big>
 
 
(simplifying the 2<sup>nd</sup> term in this replacement as necessary, and where &nbsp; <big> <math> \lceil x \rceil </math> </big> &nbsp; is the &nbsp; ''ceiling'' &nbsp; function).
 
(simplifying the 2<sup>nd</sup> term in this replacement as necessary, and where <math> \lceil x \rceil </math> is the ''ceiling'' function).
<!--
This Rosetta Code task will be using the Fibonacci greedy algorithm for computing Egyptian fractions; however, if different method is used instead, please note which method is being employed. &nbsp; Having all the programming examples use the Fibonacci greedy algorithm will make for easier comparison and compatible results.
-->
 
For this task, &nbsp; [[wp:Fraction (mathematics)#Simple.2C_common.2C_or_vulgar_fractions|<u>Proper and improper fractions</u>]] &nbsp; must be able to be expressed.
 
 
Proper &nbsp;fractions &nbsp; are of the form &nbsp; <big> <math>\tfrac{a}{b}</math> </big> &nbsp; where &nbsp; <big> <math>a</math> </big> &nbsp; and &nbsp; <big> <math>b</math> </big> &nbsp; are positive integers, such that &nbsp; <big> <math>a < b</math></big>, &nbsp; &nbsp; and
 
improper fractions are of the form &nbsp; <big> <math>\tfrac{a}{b}</math> </big> &nbsp; where &nbsp; <big> <math>a</math> </big> &nbsp; and &nbsp; <big> <math>b</math> </big> &nbsp; are positive integers, such that &nbsp; <big> <span style="font-family:times">''a'' ≥ ''b''</span></big>.
 
Proper fractions &nbsp; are of the form <math>\tfrac{a}{b}</math> where <math>a</math> and <math>b</math> are positive integers, such that <math>a < b</math>, and
<br>improper fractions are of the form <math>\tfrac{a}{b}</math> where <math>a</math> and <math>b</math> are positive integers, such that <span style="font-family:times">''a'' ≥ ''b''</span>.
 
(See the [[#REXX|REXX programming example]] to view one method of expressing the whole number part of an improper fraction.)
 
For improper fractions, the integer part of any improper fraction should be first isolated and shown preceding the Egyptian unit fractions, and be surrounded by square brackets <tt>[''n'']</tt>.
 
 
;Task requirements:
* &nbsp; show the Egyptian fractions for: <math> \tfrac{43}{48} </math> and <math> \tfrac{5}{121} </math> and <math> \tfrac{2014}{59} </math>
* &nbsp; for all proper fractions, &nbsp; <big> <math>\tfrac{a}{b}</math> </big> &nbsp; where &nbsp; <big> <math>a</math> </big> &nbsp; and &nbsp; <big> <math>b</math> </big> &nbsp; are positive one-or two-digit (decimal) integers, find and show an Egyptian fraction that has:
::* &nbsp; the largest number of terms,
::* &nbsp; the largest denominator.
* &nbsp; for all one-, two-, and three-digit integers (extra credit), &nbsp; find and show (as above). &nbsp; &nbsp; {extra credit}
 
 
;Also see:
* &nbsp; Wolfram MathWorld&trade; entry: [http://mathworld.wolfram.com/EgyptianFraction.html Egyptian fraction]
* &nbsp; Numberphile YouTube video: [https://youtu.be/aVUUbNbQkbQ Egyptian Fractions and the Greedy Algorithm]
<br><br>
 
=={{header|ALGOL 68}}==
{{works with|ALGOL 68G|Any - tested with release 2.8.3.win32}}
Based on the VB.NET sample.<br>
Uses Algol 68G's LONG LONG INT for large integers.
<syntaxhighlight lang="algol68">BEGIN # compute some Egytian fractions #
PR precision 2000 PR # set the number of digits for LONG LONG INT #
PROC gcd = ( LONG LONG INT a, b )LONG LONG INT:
IF b = 0 THEN
IF a < 0 THEN
- a
ELSE
a
FI
ELSE
gcd( b, a MOD b )
FI ; # gcd #
MODE RATIONAL = STRUCT( LONG LONG INT num, den );
MODE LISTOFRATIONAL = STRUCT( RATIONAL element, REF LISTOFRATIONAL next );
REF LISTOFRATIONAL nil list of rational = NIL;
OP TOSTRING = ( INT a )STRING: whole( a, 0 );
OP TOSTRING = ( LONG INT a )STRING: whole( a, 0 );
OP TOSTRING = ( LONG LONG INT a )STRING: whole( a, 0 );
OP TOSTRING = ( RATIONAL a )STRING:
IF den OF a = 1
THEN TOSTRING num OF a
ELSE TOSTRING num OF a + "/" + TOSTRING den OF a
FI ; # TOSTRING #
OP TOSTRING = ( REF LISTOFRATIONAL lr )STRING:
BEGIN
REF LISTOFRATIONAL p := lr;
STRING result := "[";
WHILE p ISNT nil list of rational DO
result +:= TOSTRING element OF p;
IF next OF p IS nil list of rational THEN
p := NIL
ELSE
p := next OF p;
result +:= " + "
FI
OD;
result + "]"
END ; # TOSTRING #
OP CEIL = ( LONG LONG REAL v )LONG LONG INT:
IF LONG LONG INT result := ENTIER v;
ABS v > ABS result
THEN result + 1
ELSE result
FI ; # CEIL #
OP EGYPTIAN = ( RATIONAL rp )REF LISTOFRATIONAL:
IF RATIONAL r := rp;
num OF r = 0 OR num OF r = 1
THEN HEAP LISTOFRATIONAL := ( r, nil list of rational )
ELSE
REF LISTOFRATIONAL result := nil list of rational;
REF LISTOFRATIONAL end result := nil list of rational;
PROC add = ( RATIONAL r )VOID:
IF end result IS nil list of rational THEN
result := HEAP LISTOFRATIONAL := ( r, nil list of rational );
end result := result
ELSE
next OF end result := HEAP LISTOFRATIONAL := ( r, nil list of rational );
end result := next OF end result
FI ; # add #
IF num OF r > den OF r THEN
add( RATIONAL( num OF r OVER den OF r, 1 ) );
r := ( num OF r MOD den OF r, den OF r )
FI;
PROC mod func = ( LONG LONG INT m, n )LONG LONG INT: ( ( m MOD n ) + n ) MOD n;
WHILE num OF r /= 0 DO
LONG LONG INT q = CEIL( den OF r / num OF r );
add( RATIONAL( 1, q ) );
r := RATIONAL( mod func( - ( den OF r ), num OF r ), ( den OF r ) * q )
OD;
result
FI ; # EGYPTIAN #
BEGIN # task test cases #
[]RATIONAL test cases = ( RATIONAL( 43, 48 ), RATIONAL( 5, 121 ), RATIONAL( 2014, 59 ) );
FOR r pos FROM LWB test cases TO UPB test cases DO
print( ( TOSTRING test cases[ r pos ], " -> ", TOSTRING EGYPTIAN test cases[ r pos ], newline ) )
OD;
# find the fractions with the most terms and the largest denominator #
print( ( "For rationals with numerator and denominator in 1..99:", newline ) );
RATIONAL largest denominator := ( 0, 1 );
REF LISTOFRATIONAL max denominator list := nil list of rational;
LONG LONG INT max denominator := 0;
RATIONAL most terms := ( 0, 1 );
REF LISTOFRATIONAL most terms list := nil list of rational;
INT max terms := 0;
FOR num TO 99 DO
FOR den TO 99 DO
RATIONAL r = RATIONAL( num, den );
REF LISTOFRATIONAL e := EGYPTIAN r;
REF LISTOFRATIONAL p := e;
INT terms := 0;
WHILE p ISNT nil list of rational DO
terms +:= 1;
IF den OF element OF p > max denominator THEN
largest denominator := r;
max denominator := den OF element OF p;
max denominator list := e
FI;
p := next OF p
OD;
IF terms > max terms THEN
most terms := r;
max terms := terms;
most terms list := e
FI
OD
OD;
print( ( " ", TOSTRING most terms, " has the most terms: ", TOSTRING max terms, newline
, " ", TOSTRING most terms list, newline
)
);
print( ( " ", TOSTRING largest denominator, " has the largest denominator:", newline
, " ", TOSTRING max denominator list, newline
)
)
END
END</syntaxhighlight>
{{out}}
<pre>
43/48 -> [1/2 + 1/3 + 1/16]
5/121 -> [1/25 + 1/757 + 1/763309 + 1/873960180913 + 1/1527612795642093418846225]
2014/59 -> [34 + 1/8 + 1/95 + 1/14947 + 1/670223480]
For rationals with numerator and denominator in 1..99:
97/53 has the most terms: 9
[1 + 1/2 + 1/4 + 1/13 + 1/307 + 1/120871 + 1/20453597227 + 1/697249399186783218655 + 1/1458470173998990524806872692984177836808420]
8/97 has the largest denominator:
[1/13 + 1/181 + 1/38041 + 1/1736503177 + 1/3769304102927363485 + 1/18943537893793408504192074528154430149 + 1/538286441900380211365817285104907086347439746130226973253778132494225813153 + 1/579504587067542801713103191859918608251030291952195423583529357653899418686342360361798689053273749372615043661810228371898539583862011424993909789665]
</pre>
 
=={{header|C}}==
Output has limited accuracy as noted by comments. The problem requires bigint support to be completely accurate.
<syntaxhighlight lang="c">#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
 
typedef int64_t integer;
 
struct Pair {
integer md;
int tc;
};
 
integer mod(integer x, integer y) {
return ((x % y) + y) % y;
}
 
integer gcd(integer a, integer b) {
if (0 == a) return b;
if (0 == b) return a;
if (a == b) return a;
if (a > b) return gcd(a - b, b);
return gcd(a, b - a);
}
 
void write0(bool show, char *str) {
if (show) {
printf(str);
}
}
 
void write1(bool show, char *format, integer a) {
if (show) {
printf(format, a);
}
}
 
void write2(bool show, char *format, integer a, integer b) {
if (show) {
printf(format, a, b);
}
}
 
struct Pair egyptian(integer x, integer y, bool show) {
struct Pair ret;
integer acc = 0;
bool first = true;
 
ret.tc = 0;
ret.md = 0;
 
write2(show, "Egyptian fraction for %lld/%lld: ", x, y);
while (x > 0) {
integer z = (y + x - 1) / x;
if (z == 1) {
acc++;
} else {
if (acc > 0) {
write1(show, "%lld + ", acc);
first = false;
acc = 0;
ret.tc++;
} else if (first) {
first = false;
} else {
write0(show, " + ");
}
if (z > ret.md) {
ret.md = z;
}
write1(show, "1/%lld", z);
ret.tc++;
}
x = mod(-y, x);
y = y * z;
}
if (acc > 0) {
write1(show, "%lld", acc);
ret.tc++;
}
write0(show, "\n");
 
return ret;
}
 
int main() {
struct Pair p;
integer nm = 0, dm = 0, dmn = 0, dmd = 0, den = 0;;
int tm, i, j;
 
egyptian(43, 48, true);
egyptian(5, 121, true); // final term cannot be represented correctly
egyptian(2014, 59, true);
 
tm = 0;
for (i = 1; i < 100; i++) {
for (j = 1; j < 100; j++) {
p = egyptian(i, j, false);
if (p.tc > tm) {
tm = p.tc;
nm = i;
dm = j;
}
if (p.md > den) {
den = p.md;
dmn = i;
dmd = j;
}
}
}
printf("Term max is %lld/%lld with %d terms.\n", nm, dm, tm); // term max is correct
printf("Denominator max is %lld/%lld\n", dmn, dmd); // denominator max is not correct
egyptian(dmn, dmd, true); // enough digits cannot be represented without bigint
 
return 0;
}</syntaxhighlight>
{{out}}
<pre>Egyptian fraction for 43/48: 1/2 + 1/3 + 1/16
Egyptian fraction for 5/121: 1/25 + 1/757 + 1/763309 + 1/873960180913 + 1/1025410058030422033
Egyptian fraction for 2014/59: 34 + 1/8 + 1/95 + 1/14947 + 1/670223480
Term max is 97/53 with 9 terms.
Denominator max is 69/97
Egyptian fraction for 69/97: 1/2 + 1/5 + 1/89 + 1/9593 + 1/118309099 + 1/32659766662805104 + 1/2591418766870639376</pre>
 
=={{header|C sharp|C#}}==
{{trans|Visual Basic .NET}}
<syntaxhighlight lang="csharp">using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Text;
using System.Threading.Tasks;
 
namespace EgyptianFractions {
class Program {
class Rational : IComparable<Rational>, IComparable<int> {
public BigInteger Num { get; }
public BigInteger Den { get; }
 
public Rational(BigInteger n, BigInteger d) {
var c = Gcd(n, d);
Num = n / c;
Den = d / c;
if (Den < 0) {
Num = -Num;
Den = -Den;
}
}
 
public Rational(BigInteger n) {
Num = n;
Den = 1;
}
 
public override string ToString() {
if (Den == 1) {
return Num.ToString();
} else {
return string.Format("{0}/{1}", Num, Den);
}
}
 
public Rational Add(Rational rhs) {
return new Rational(Num * rhs.Den + rhs.Num * Den, Den * rhs.Den);
}
 
public Rational Sub(Rational rhs) {
return new Rational(Num * rhs.Den - rhs.Num * Den, Den * rhs.Den);
}
 
public int CompareTo(Rational rhs) {
var ad = Num * rhs.Den;
var bc = Den * rhs.Num;
return ad.CompareTo(bc);
}
 
public int CompareTo(int rhs) {
var ad = Num * rhs;
var bc = Den * rhs;
return ad.CompareTo(bc);
}
}
 
static BigInteger Gcd(BigInteger a, BigInteger b) {
if (b == 0) {
if (a < 0) {
return -a;
} else {
return a;
}
} else {
return Gcd(b, a % b);
}
}
 
static List<Rational> Egyptian(Rational r) {
List<Rational> result = new List<Rational>();
 
if (r.CompareTo(1) >= 0) {
if (r.Den == 1) {
result.Add(r);
result.Add(new Rational(0));
return result;
}
result.Add(new Rational(r.Num / r.Den));
r = r.Sub(result[0]);
}
 
BigInteger modFunc(BigInteger m, BigInteger n) {
return ((m % n) + n) % n;
}
 
while (r.Num != 1) {
var q = (r.Den + r.Num - 1) / r.Num;
result.Add(new Rational(1, q));
r = new Rational(modFunc(-r.Den, r.Num), r.Den * q);
}
 
result.Add(r);
return result;
}
 
static string FormatList<T>(IEnumerable<T> col) {
StringBuilder sb = new StringBuilder();
var iter = col.GetEnumerator();
 
sb.Append('[');
if (iter.MoveNext()) {
sb.Append(iter.Current);
}
while (iter.MoveNext()) {
sb.AppendFormat(", {0}", iter.Current);
}
sb.Append(']');
 
return sb.ToString();
}
 
static void Main() {
List<Rational> rs = new List<Rational> {
new Rational(43, 48),
new Rational(5, 121),
new Rational(2014, 59)
};
foreach (var r in rs) {
Console.WriteLine("{0} => {1}", r, FormatList(Egyptian(r)));
}
 
var lenMax = Tuple.Create(0UL, new Rational(0));
var denomMax = Tuple.Create(BigInteger.Zero, new Rational(0));
 
var query = (from i in Enumerable.Range(1, 100)
from j in Enumerable.Range(1, 100)
select new Rational(i, j))
.Distinct()
.ToList();
foreach (var r in query) {
var e = Egyptian(r);
ulong eLen = (ulong) e.Count;
var eDenom = e.Last().Den;
if (eLen > lenMax.Item1) {
lenMax = Tuple.Create(eLen, r);
}
if (eDenom > denomMax.Item1) {
denomMax = Tuple.Create(eDenom, r);
}
}
 
Console.WriteLine("Term max is {0} with {1} terms", lenMax.Item2, lenMax.Item1);
var dStr = denomMax.Item1.ToString();
Console.WriteLine("Denominator max is {0} with {1} digits {2}...{3}", denomMax.Item2, dStr.Length, dStr.Substring(0, 5), dStr.Substring(dStr.Length - 5, 5));
}
}
}</syntaxhighlight>
{{out}}
<pre>43/48 => [1/2, 1/3, 1/16]
5/121 => [1/25, 1/757, 1/763309, 1/873960180913, 1/1527612795642093418846225]
2014/59 => [34, 1/8, 1/95, 1/14947, 1/670223480]
Term max is 97/53 with 9 terms
Denominator max is 8/97 with 150 digits 57950...89665</pre>
 
=={{header|C++}}==
{{libheader|Boost}}
The C++ standard library does not have a "big integer" type, so this solution uses the Boost library.
<syntaxhighlight lang="cpp">#include <boost/multiprecision/cpp_int.hpp>
#include <iostream>
#include <optional>
#include <sstream>
#include <string>
#include <vector>
 
typedef boost::multiprecision::cpp_int integer;
 
struct fraction {
fraction(const integer& n, const integer& d)
: numerator(n), denominator(d) {}
integer numerator;
integer denominator;
};
 
integer mod(const integer& x, const integer& y) { return ((x % y) + y) % y; }
 
size_t count_digits(const integer& i) {
std::ostringstream os;
os << i;
return os.str().length();
}
 
std::string to_string(const integer& i) {
const int max_digits = 20;
std::ostringstream os;
os << i;
std::string s = os.str();
if (s.length() > max_digits)
s.replace(max_digits / 2, s.length() - max_digits, "...");
return s;
}
 
std::ostream& operator<<(std::ostream& out, const fraction& f) {
return out << to_string(f.numerator) << '/' << to_string(f.denominator);
}
 
void egyptian(const fraction& f, std::vector<fraction>& result) {
result.clear();
integer x = f.numerator, y = f.denominator;
while (x > 0) {
integer z = (y + x - 1) / x;
result.emplace_back(1, z);
x = mod(-y, x);
y = y * z;
}
}
 
void print_egyptian(const std::vector<fraction>& result) {
if (result.empty())
return;
auto i = result.begin();
std::cout << *i++;
for (; i != result.end(); ++i)
std::cout << " + " << *i;
std::cout << '\n';
}
 
void print_egyptian(const fraction& f) {
std::cout << "Egyptian fraction for " << f << ": ";
integer x = f.numerator, y = f.denominator;
if (x > y) {
std::cout << "[" << x / y << "] ";
x = x % y;
}
std::vector<fraction> result;
egyptian(fraction(x, y), result);
print_egyptian(result);
std::cout << '\n';
}
 
void show_max_terms_and_max_denominator(const integer& limit) {
size_t max_terms = 0;
std::optional<fraction> max_terms_fraction, max_denominator_fraction;
std::vector<fraction> max_terms_result;
integer max_denominator = 0;
std::vector<fraction> max_denominator_result;
std::vector<fraction> result;
for (integer b = 2; b < limit; ++b) {
for (integer a = 1; a < b; ++a) {
fraction f(a, b);
egyptian(f, result);
if (result.size() > max_terms) {
max_terms = result.size();
max_terms_result = result;
max_terms_fraction = f;
}
const integer& denominator = result.back().denominator;
if (denominator > max_denominator) {
max_denominator = denominator;
max_denominator_result = result;
max_denominator_fraction = f;
}
}
}
std::cout
<< "Proper fractions with most terms and largest denominator, limit = "
<< limit << ":\n\n";
std::cout << "Most terms (" << max_terms
<< "): " << max_terms_fraction.value() << " = ";
print_egyptian(max_terms_result);
std::cout << "\nLargest denominator ("
<< count_digits(max_denominator_result.back().denominator)
<< " digits): " << max_denominator_fraction.value() << " = ";
print_egyptian(max_denominator_result);
}
 
int main() {
print_egyptian(fraction(43, 48));
print_egyptian(fraction(5, 121));
print_egyptian(fraction(2014, 59));
show_max_terms_and_max_denominator(100);
show_max_terms_and_max_denominator(1000);
return 0;
}</syntaxhighlight>
 
{{out}}
<pre>
Egyptian fraction for 43/48: 1/2 + 1/3 + 1/16
 
Egyptian fraction for 5/121: 1/25 + 1/757 + 1/763309 + 1/873960180913 + 1/1527612795...3418846225
 
Egyptian fraction for 2014/59: [34] 1/8 + 1/95 + 1/14947 + 1/670223480
 
Proper fractions with most terms and largest denominator, limit = 100:
 
Most terms (8): 44/53 = 1/2 + 1/4 + 1/13 + 1/307 + 1/120871 + 1/20453597227 + 1/6972493991...6783218655 + 1/1458470173...7836808420
 
Largest denominator (150 digits): 8/97 = 1/13 + 1/181 + 1/38041 + 1/1736503177 + 1/3769304102927363485 + 1/1894353789...8154430149 + 1/5382864419...4225813153 + 1/5795045870...3909789665
Proper fractions with most terms and largest denominator, limit = 1000:
 
Most terms (13): 641/796 = 1/2 + 1/4 + 1/19 + 1/379 + 1/159223 + 1/28520799973 + 1/9296411783...1338400861 + 1/1008271507...4174730681 + 1/1219933718...8484537833 + 1/1860297848...1025882029 + 1/4614277444...8874327093 + 1/3193733450...1456418881 + 1/2039986670...2410165441
 
Largest denominator (2847 digits): 36/457 = 1/13 + 1/541 + 1/321409 + 1/114781617793 + 1/1482167225...0844346913 + 1/2510651068...4290086881 + 1/7353930250...3326272641 + 1/6489634815...7391865217 + 1/5264420004...5476206145 + 1/3695215730...1238141889 + 1/2048192894...4706590593 + 1/8390188268...5525592705
</pre>
 
=={{header|Common Lisp}}==
<langsyntaxhighlight lang="lisp">(defun egyption-fractions (x y &optional acc)
(let* ((a (/ x y)))
(cond
Line 55 ⟶ 616:
#'>
:key #'cdr)))
</syntaxhighlight>
</lang>
 
{{out}}
Line 84 ⟶ 645:
Assuming the Python entry is correct, this code is equivalent. This requires the D module of the Arithmetic/Rational task.
{{trans|Python}}
<langsyntaxhighlight lang="d">import std.stdio, std.bigint, std.algorithm, std.range, std.conv, std.typecons,
arithmetic_rational: Rat = Rational;
 
Line 131 ⟶ 692:
writefln("Denominator max is %s with %d digits %s...%s",
denomMax[1], dStr.length, dStr[0 .. 5], dStr[$ - 5 .. $]);
}</langsyntaxhighlight>
{{out}}
<pre>43/48 => 1/2 1/3 1/16
Line 138 ⟶ 699:
Term max is 97/53 with 9 terms
Denominator max is 8/97 with 150 digits 57950...89665</pre>
 
=={{header|Erlang}}==
<syntaxhighlight lang="erlang">-module(egypt).
 
-import(lists, [reverse/1, seq/2]).
-export([frac/2, show/2, rosetta/0]).
 
rosetta() ->
Fractions = [{N, D, second(frac(N, D))} || N <- seq(2,99), D <- seq(N+1, 99)],
{Longest, A1, B1} = findmax(fun length/1, Fractions),
io:format("~b/~b has ~b terms.~n", [A1, B1, Longest]),
{Largest, A2, B2} = findmax(fun (L) -> hd(reverse(L)) end, Fractions),
io:format("~b/~b has a really long denominator. (~b)~n", [A2, B2, Largest]).
 
second({_, B}) -> B.
 
findmax(Fn, L) -> findmax(Fn, L, 0, 0, 0).
findmax(_, [], M, A, B) -> {M, A, B};
findmax(Fn, [{A,B,Frac}|Fracs], M, A0, B0) ->
Val = Fn(Frac),
case Val > M of
true -> findmax(Fn, Fracs, Val, A, B);
false -> findmax(Fn, Fracs, M, A0, B0)
end.
 
show(A, B) ->
{W, R} = frac(A, B),
case W of
0 -> ok;
_ -> io:format("[~b] ", [W])
end,
case R of
[] -> ok;
[D0|Ds] ->
io:format("1/~b ", [D0]),
[io:format("+ 1/~b ", [D]) || D <- Ds],
ok
end.
 
frac(A, B) ->
{A div B, reverse(proper(A rem B, B, []))}.
 
proper(0, _, L) -> L;
proper(1, Y, L) -> [Y|L];
proper(X, Y, L) ->
D = ceildiv(Y, X),
X2 = mod(-Y, X),
Y2 = Y*ceildiv(Y, X),
proper(X2, Y2, [D|L]).
 
ceildiv(A, B) ->
Q = A div B,
case A rem B of
0 -> Q;
_ -> Q+1
end.
 
mod(A, M) ->
B = A rem M,
if
B < 0 -> B + M;
true -> B
end.
</syntaxhighlight>
 
{{out}}
<pre>
129> egypt:show(43,48).
1/2 + 1/3 + 1/16 ok
130> egypt:show(5,121).
1/25 + 1/757 + 1/763309 + 1/873960180913 + 1/1527612795642093418846225 ok
131> egypt:show(2014,59).
[34] 1/8 + 1/95 + 1/14947 + 1/670223480 ok
132> egypt:rosetta().
8/97 has 8 terms.
8/97 has a really long denominator. (579504587067542801713103191859918608251030291952195423583529357653899418686342360361798689053273749372615043661810228371898539583862011424993909789665)
ok
</pre>
 
=={{header|F_Sharp|F#}}==
<syntaxhighlight lang="fsharp">
// Greedy algorithm for Egyptian fractions. Nigel Galloway: February 1st., 2023
open Mathnet.Numerics
let fN(g:BigRational)=match bigint.DivRem(g.Denominator,g.Numerator) with (n,g) when g=0I->n |(n,_)->n+1I
let fG(n:BigRational)=Seq.unfold(fun(g:BigRational)->if g.Numerator=0I then None else let i=fN g in Some(i,(g-1N/(BigRational.FromBigInt i))))(n)
let fL(n:bigint,g:seq<bigint>)=printf "%A" n; g|>Seq.iter(printf "+1/%A"); printfn ""
let f2ef(i:BigRational)=let n,g=bigint.DivRem(i.Numerator,i.Denominator) in (n,fG(BigRational.FromBigIntFraction(g,i.Denominator)))
[43N/48N;5N/121N;2014N/59N]|>List.iter(f2ef>>fL)
let n,_=List.allPairs [1N..99N] [1N..99N]|>Seq.map(fun(n,g)->let n=n/g in (n,f2ef n))|>Seq.maxBy(fun(_,(n,g))->Seq.length g + if n>0I then 1 else 0) in printf "%A->" n; (f2ef>>fL)n
let n,_=List.allPairs [1N..999N] [1N..999N]|>Seq.map(fun(n,g)->let n=n/g in (n,f2ef n))|>Seq.maxBy(fun(_,(n,g))->Seq.length g + if n>0I then 1 else 0) in printf "%A->" n; (f2ef>>fL)n
let n,_=List.allPairs [1N..99N] [1N..99N]|>Seq.map(fun(n,g)->let n=n/g in (n,f2ef n))|>Seq.maxBy(fun(_,(n,g))->if Seq.isEmpty g then 0I else Seq.max g) in printf "%A->" n; (f2ef>>fL)n
let n,_=List.allPairs [1N..999N] [1N..999N]|>Seq.map(fun(n,g)->let n=n/g in (n,f2ef n))|>Seq.maxBy(fun(_,(n,g))->if Seq.isEmpty g then 0I else Seq.max g) in printf "%A->" n; (f2ef>>fL)n
</syntaxhighlight>
{{out}}
<pre>
0+1/2+1/3+1/16
0+1/25+1/757+1/763309+1/873960180913+1/1527612795642093418846225
34+1/8+1/95+1/14947+1/670223480
97/53N->1+1/2+1/4+1/13+1/307+1/120871+1/20453597227+1/697249399186783218655+1/1458470173998990524806872692984177836808420
493/457N->1+1/13+1/541+1/321409+1/114781617793+1/14821672255960844346913+1/251065106814993628596500876449600804290086881+1/73539302503361520198362339236500915390885795679264404865887253300925727812630083326272641+1/6489634815217096741758907148982381236931234341288936993640630568353888026513046373352130623124225014404918014072680355409470797372507720812828610332359154836067922616607391865217+1/52644200043597301715163084170074049765863371513744701000308778672552161021188727897845435784419167578097570308323221316037189809321236639774156001218848770417914304730719451756764847141999454715415348579218576135692260706546084789833559164567239198064491721524233401718052341737694961761810858726456915514545036448002629051435498625211733293978125476206145+1/3695215730973720191743335450900515442837964059737103132125137784392340041085824276783333540815086968586494259680343732030671448522298751008735945486795776365973142745077411841504712940444458881229478108614230774637316342940593842925604630011475333378620376362943942755446627099104200059416153812858633723638212819657597061963458758259287734950993940819872945202809437805131650984566124057319228963533088559443909352453788455968978250113376533423265233637558939144535732287317303130488802163512444658441011602922480039143050047663394967808639154754442570791381496210122415541628843804495020590646687354364355396925939868087995781911240513904752765014910531863571167632659092232428610030201325032663259931238141889+1/20481928947653467858867964360215698922460866349989714221296388791180533521147068328398292448571350580917144516243144419767021450972552458770890215041236338405232471846144964422722088363577942656244304369314740680337368003341749927848292268159627280776486153786277410225081205358330757686606252814923029488556248114378465151886875778980493919811102286892641254175976181063891774788890129279669791215911728886439002027991447164421080590166911130116483359749418047307595497010369457711350953018694479942850146580996402187310635505278301929397030213544531068769667892360925519410013180703331321321833900350008776368272790481252519169303988218210095146759870287941250090204506960847016059468728275311477613271084474766715488264771177830115028195215223644336345646870679050787515340804351339449474385172464387868299006904638274425855008729765086091731260299397062138670321522563954731398813138738073326593694555049353805161855854036423870334342280080335804850998490793742536882308453307029152812821729798744074167237835462214043679643723245065093600037959124662392297413473130606861784229249604290090458912391096328362137163951398211801143455350336317188806956746282700489013366856863803112203078858200161688528939040348825835610989725020068306497091337571398894447440161081470240965873628208205669354804691958270783090585006358905094926094885655359774269830169287513005586562246433405044654325439410730648108371520856384706590593+1/839018826833450186636781520007011999269820404906753180244759299287837378895397605613261469995626498719289835112392530430840514102146998625666594756995273418015600023494049208108894185781774002683063204252356172520941088783702738286944210460710059319691268110283467445381026653628599765684739105388642310044785844902157076919003735231543781785073393176144167688252446541416466418608465458502997971425428342769433127784560570193376772878336217849260872114137931351960543608384244009505664253173875705234889570853924105640193619301332776989688248555027054395237907581951261868280899150574360164800187964167274323078311078867593844043149124596271281252530924719121766925749760855109100066731841478262812686642693395896229983745226277793055820609058348269152190083695704685769622011655159174272326647342695589818127126303038171968768650476413027459205291075571637957597356820188031655122749743652301268394542123970892422944335857917641636041892192547135178153602038877677614358281581103685526041329841496863410305888255234495015115912388514981113593387572720476744188169200130515719608747338810136728267784013352396910979904545913458536243327311977805126410065576961237640824852114328884086581542091492600312838425666927627674227053793897767395465326589843035773944346372949759909905561209334216847158156644884281300512699910530092870919061876615770708519243818676366245477462042294267674677954783726990349386117468071932874021023714524610740225814235147693954027910741673103980749749728106483987721602738673173009362802337092908847797499475895347112889339502928407808058670297722175686638678788738689803945574002805677250463286479363670076942509109589495377221095405979217163821481666646160815221224686562530536116613645305335922819524037829878961518170177968768364853399057357772141655622381280196908637031556436461404285930426436983658106288733881761514992109680298995922754466040011586713812553117621857109517258943846004179432521131844156242428351270188803919554398620084668514054504414062276012292497375238210886595006249453460414790147611422121782194848803348777061816460876697945418158442269512987729152441940326466631610424906158237288218706447963113019239557885486647314085357651895226117364760315394354624547919209138539180807829672545924239541758108877100331729470119526373928796447673951888289511964811633025369821156695934557103429921063387965046715070102916811976552584464153981214277622597308113449320462341683055200576571910241686615924531368198770946893858410058348221985603151428153382461711196734214085852523778422630907646235900752317571022131569421231196329080023952364788544301495422061066036911772385739659997665503832444529713544286955548310166168837889046149061296461059432238621602179724809510024772127497080258401694929973105184832214622785679651550368465524821062859837409907538269572622296774545103747438431266995525592705
8/97N->0+1/13+1/181+1/38041+1/1736503177+1/3769304102927363485+1/18943537893793408504192074528154430149+1/538286441900380211365817285104907086347439746130226973253778132494225813153+1/579504587067542801713103191859918608251030291952195423583529357653899418686342360361798689053273749372615043661810228371898539583862011424993909789665
36/457N->0+1/13+1/541+1/321409+1/114781617793+1/14821672255960844346913+1/251065106814993628596500876449600804290086881+1/73539302503361520198362339236500915390885795679264404865887253300925727812630083326272641+1/6489634815217096741758907148982381236931234341288936993640630568353888026513046373352130623124225014404918014072680355409470797372507720812828610332359154836067922616607391865217+1/52644200043597301715163084170074049765863371513744701000308778672552161021188727897845435784419167578097570308323221316037189809321236639774156001218848770417914304730719451756764847141999454715415348579218576135692260706546084789833559164567239198064491721524233401718052341737694961761810858726456915514545036448002629051435498625211733293978125476206145+1/3695215730973720191743335450900515442837964059737103132125137784392340041085824276783333540815086968586494259680343732030671448522298751008735945486795776365973142745077411841504712940444458881229478108614230774637316342940593842925604630011475333378620376362943942755446627099104200059416153812858633723638212819657597061963458758259287734950993940819872945202809437805131650984566124057319228963533088559443909352453788455968978250113376533423265233637558939144535732287317303130488802163512444658441011602922480039143050047663394967808639154754442570791381496210122415541628843804495020590646687354364355396925939868087995781911240513904752765014910531863571167632659092232428610030201325032663259931238141889+1/20481928947653467858867964360215698922460866349989714221296388791180533521147068328398292448571350580917144516243144419767021450972552458770890215041236338405232471846144964422722088363577942656244304369314740680337368003341749927848292268159627280776486153786277410225081205358330757686606252814923029488556248114378465151886875778980493919811102286892641254175976181063891774788890129279669791215911728886439002027991447164421080590166911130116483359749418047307595497010369457711350953018694479942850146580996402187310635505278301929397030213544531068769667892360925519410013180703331321321833900350008776368272790481252519169303988218210095146759870287941250090204506960847016059468728275311477613271084474766715488264771177830115028195215223644336345646870679050787515340804351339449474385172464387868299006904638274425855008729765086091731260299397062138670321522563954731398813138738073326593694555049353805161855854036423870334342280080335804850998490793742536882308453307029152812821729798744074167237835462214043679643723245065093600037959124662392297413473130606861784229249604290090458912391096328362137163951398211801143455350336317188806956746282700489013366856863803112203078858200161688528939040348825835610989725020068306497091337571398894447440161081470240965873628208205669354804691958270783090585006358905094926094885655359774269830169287513005586562246433405044654325439410730648108371520856384706590593+1/839018826833450186636781520007011999269820404906753180244759299287837378895397605613261469995626498719289835112392530430840514102146998625666594756995273418015600023494049208108894185781774002683063204252356172520941088783702738286944210460710059319691268110283467445381026653628599765684739105388642310044785844902157076919003735231543781785073393176144167688252446541416466418608465458502997971425428342769433127784560570193376772878336217849260872114137931351960543608384244009505664253173875705234889570853924105640193619301332776989688248555027054395237907581951261868280899150574360164800187964167274323078311078867593844043149124596271281252530924719121766925749760855109100066731841478262812686642693395896229983745226277793055820609058348269152190083695704685769622011655159174272326647342695589818127126303038171968768650476413027459205291075571637957597356820188031655122749743652301268394542123970892422944335857917641636041892192547135178153602038877677614358281581103685526041329841496863410305888255234495015115912388514981113593387572720476744188169200130515719608747338810136728267784013352396910979904545913458536243327311977805126410065576961237640824852114328884086581542091492600312838425666927627674227053793897767395465326589843035773944346372949759909905561209334216847158156644884281300512699910530092870919061876615770708519243818676366245477462042294267674677954783726990349386117468071932874021023714524610740225814235147693954027910741673103980749749728106483987721602738673173009362802337092908847797499475895347112889339502928407808058670297722175686638678788738689803945574002805677250463286479363670076942509109589495377221095405979217163821481666646160815221224686562530536116613645305335922819524037829878961518170177968768364853399057357772141655622381280196908637031556436461404285930426436983658106288733881761514992109680298995922754466040011586713812553117621857109517258943846004179432521131844156242428351270188803919554398620084668514054504414062276012292497375238210886595006249453460414790147611422121782194848803348777061816460876697945418158442269512987729152441940326466631610424906158237288218706447963113019239557885486647314085357651895226117364760315394354624547919209138539180807829672545924239541758108877100331729470119526373928796447673951888289511964811633025369821156695934557103429921063387965046715070102916811976552584464153981214277622597308113449320462341683055200576571910241686615924531368198770946893858410058348221985603151428153382461711196734214085852523778422630907646235900752317571022131569421231196329080023952364788544301495422061066036911772385739659997665503832444529713544286955548310166168837889046149061296461059432238621602179724809510024772127497080258401694929973105184832214622785679651550368465524821062859837409907538269572622296774545103747438431266995525592705
</pre>
=={{header|Factor}}==
<syntaxhighlight lang="factor">USING: backtrack formatting fry kernel locals make math
math.functions math.ranges sequences ;
IN: rosetta-code.egyptian-fractions
 
: >improper ( r -- str ) >fraction "%d/%d" sprintf ;
 
: improper ( x y -- a b ) [ /i ] [ [ rem ] [ nip ] 2bi / ] 2bi ;
 
:: proper ( x y -- a b )
y x / ceiling :> d1 1 d1 / y neg x rem y d1 * / ;
: expand ( a -- b c )
>fraction 2dup > [ improper ] [ proper ] if ;
 
: egyptian-fractions ( x -- seq )
[ [ expand [ , ] dip dup 0 = not ] loop drop ] { } make ;
 
: part1 ( -- )
43/48 5/121 2014/59 [
[ >improper ] [ egyptian-fractions ] bi
"%s => %[%u, %]\n" printf
] tri@ ;
 
: all-longest ( seq -- seq )
dup longest length '[ length _ = ] filter ;
 
: (largest-denominator) ( seq -- n )
[ denominator ] map supremum ;
 
: most-terms ( seq -- )
all-longest [ [ sum ] map ] [ first length ] bi
"most terms: %[%u, %] => %d\n" printf ;
 
: largest-denominator ( seq -- )
[ (largest-denominator) ] supremum-by
[ sum ] [ (largest-denominator) ] bi
"largest denominator: %u => %d\n" printf ;
 
: part2 ( -- )
[
99 [1,b] amb-lazy dup [1,b] amb-lazy swap /
egyptian-fractions
] bag-of [ most-terms ] [ largest-denominator ] bi ;
 
: egyptian-fractions-demo ( -- ) part1 part2 ;
 
MAIN: egyptian-fractions-demo</syntaxhighlight>
{{out}}
<pre>
43/48 => { 1/2, 1/3, 1/16 }
5/121 => { 1/25, 1/757, 1/763309, 1/873960180913, 1/1527612795642093418846225 }
2014/59 => { 34, 1/8, 1/95, 1/14947, 1/670223480 }
most terms: { 44/53, 8/97 } => 8
largest denominator: 8/97 => 579504587067542801713103191859918608251030291952195423583529357653899418686342360361798689053273749372615043661810228371898539583862011424993909789665
</pre>
 
=={{header|FreeBASIC}}==
{{libheader|GMP}}
<langsyntaxhighlight lang="freebasic">' version 16-01-2017
' compile with: fbc -s console
 
Line 308 ⟶ 1,029:
Print : Print "hit any key to end program"
Sleep
End</langsyntaxhighlight>
{{out}}
<pre>43/48 = 1/2 + 1/3 + 1/16
Line 324 ⟶ 1,045:
Largest number of terms is 13 for 641/796, 529/914
Largest size for denominator is 2847 for 36/457, 529/914</pre>
 
=={{header|Frink}}==
<syntaxhighlight lang="frink">
frac[p, q] :=
{
a = makeArray[[0]]
if p > q
{
a.push[floor[p / q]]
p = p mod q
}
while p > 1
{
d = ceil[q / p]
a.push[1/d]
[p, q] = [-q mod p, d q]
}
if p == 1
a.push[1/q]
a
}
 
showApproximations[false]
 
egypt[p, q] := join[" + ", frac[p, q]]
 
rosetta[] :=
{
lMax = 0
longest = 0
 
dMax = 0
biggest = 0
 
for n = 1 to 99
for d = n+1 to 99
{
egypt = frac[n, d]
if length[egypt] > lMax
{
lMax = length[egypt]
longest = n/d
}
d2 = denominator[last[egypt, 1]@0]
if d2 > dMax
{
dMax = d2
biggest = n/d
}
}
 
println["The fraction with the largest number of terms is $longest"]
println["The fraction with the largest denominator is $biggest"]
}
</syntaxhighlight>
{{Out}}
<pre>
rosetta[]
The fraction with the largest number of terms is 8/97
The fraction with the largest denominator is 8/97
 
egypt[43,48]
1/2 + 1/3 + 1/16
 
egypt[5,121]
1/25 + 1/757 + 1/763309 + 1/873960180913 + 1/1527612795642093418846225
 
egypt[2014,59]
34 + 1/8 + 1/95 + 1/14947 + 1/670223480
</pre>
 
=={{header|Fōrmulæ}}==
 
{{FormulaeEntry|page=https://formulae.org/?script=examples/Egyptian_fractions}}
 
'''Solution'''
 
[[File:Fōrmulæ - Egyptian fractions 01.png]]
 
'''Test cases part 1'''
 
[[File:Fōrmulæ - Egyptian fractions 02.png]]
 
[[File:Fōrmulæ - Egyptian fractions 03.png]]
 
[[File:Fōrmulæ - Egyptian fractions 04.png]]
 
[[File:Fōrmulæ - Egyptian fractions 05.png]]
 
[[File:Fōrmulæ - Egyptian fractions 06.png]]
 
[[File:Fōrmulæ - Egyptian fractions 07.png]]
 
'''Test cases part 2'''
 
[[File:Fōrmulæ - Egyptian fractions 08.png]]
 
[[File:Fōrmulæ - Egyptian fractions 09.png]]
 
[[File:Fōrmulæ - Egyptian fractions 10.png]]
 
[[File:Fōrmulæ - Egyptian fractions 11.png]]
 
[[File:Fōrmulæ - Egyptian fractions 12.png]]
 
[[File:Fōrmulæ - Egyptian fractions 13.png]]
 
[[File:Fōrmulæ - Egyptian fractions 14.png]]
 
=={{header|Go}}==
{{trans|Kotlin}}
... except that Go already has support for arbitrary precision rational numbers in its standard library.
<langsyntaxhighlight lang="go">package main
 
import (
Line 464 ⟶ 1,293:
fmt.Println(" fraction(s) with this denominator :", maxDenFracs)
}
}</langsyntaxhighlight>
 
{{out}}
Line 486 ⟶ 1,315:
 
=={{header|Haskell}}==
<langsyntaxhighlight lang="haskell">import Data.Ratio (Ratio, (%), denominator, numerator)
 
egyptianFraction :: Integral a => Ratio a -> [Ratio a]
Line 498 ⟶ 1,327:
x = numerator n
y = denominator n
r = y `div` x + 1</langsyntaxhighlight>
 
'''Testing''':
<langsyntaxhighlight lang="haskell">λ> :m Test.QuickCheck
λ> quickCheck (\n -> n == (sum $ egiptianFractionegyptianFraction n))
+++ OK, passed 100 tests.</langsyntaxhighlight>
 
'''Tasks''':
<langsyntaxhighlight lang="haskell">import Data.List (intercalate, maximumBy)
import Data.Ord (comparing)
 
Line 528 ⟶ 1,357:
| a <- [1 .. n]
, b <- [1 .. n]
, a < b ]</langsyntaxhighlight>
 
<langsyntaxhighlight lang="haskell">λ> task1
43 % 48 = 1 % 2 + 1 % 3 + 1 % 16
5 % 121 = 1 % 25 + 1 % 757 + 1 % 763309 + 1 % 873960180913 + 1 % 1527612795642093418846225
Line 542 ⟶ 1,371:
λ> task22 999
(529 % 914, 839018826833450186636781520007011999269820404906753180244759299287837378895397605613261469995626498719289835112392530430840514102146998625666594756995273418015600023494049208108894185781774002683063204252356172520941088783702738286944210460710059319691268110283467445381026653628599765684739105388642310044785844902157076919003735231543781785073393176144167688252446541416466418608465458502997971425428342769433127784560570193376772878336217849260872114137931351960543608384244009505664253173875705234889570853924105640193619301332776989688248555027054395237907581951261868280899150574360164800187964167274323078311078867593844043149124596271281252530924719121766925749760855109100066731841478262812686642693395896229983745226277793055820609058348269152190083695704685769622011655159174272326647342695589818127126303038171968768650476413027459205291075571637957597356820188031655122749743652301268394542123970892422944335857917641636041892192547135178153602038877677614358281581103685526041329841496863410305888255234495015115912388514981113593387572720476744188169200130515719608747338810136728267784013352396910979904545913458536243327311977805126410065576961237640824852114328884086581542091492600312838425666927627674227053793897767395465326589843035773944346372949759909905561209334216847158156644884281300512699910530092870919061876615770708519243818676366245477462042294267674677954783726990349386117468071932874021023714524610740225814235147693954027910741673103980749749728106483987721602738673173009362802337092908847797499475895347112889339502928407808058670297722175686638678788738689803945574002805677250463286479363670076942509109589495377221095405979217163821481666646160815221224686562530536116613645305335922819524037829878961518170177968768364853399057357772141655622381280196908637031556436461404285930426436983658106288733881761514992109680298995922754466040011586713812553117621857109517258943846004179432521131844156242428351270188803919554398620084668514054504414062276012292497375238210886595006249453460414790147611422121782194848803348777061816460876697945418158442269512987729152441940326466631610424906158237288218706447963113019239557885486647314085357651895226117364760315394354624547919209138539180807829672545924239541758108877100331729470119526373928796447673951888289511964811633025369821156695934557103429921063387965046715070102916811976552584464153981214277622597308113449320462341683055200576571910241686615924531368198770946893858410058348221985603151428153382461711196734214085852523778422630907646235900752317571022131569421231196329080023952364788544301495422061066036911772385739659997665503832444529713544286955548310166168837889046149061296461059432238621602179724809510024772127497080258401694929973105184832214622785679651550368465524821062859837409907538269572622296774545103747438431266995525592705)
</syntaxhighlight>
</lang>
 
=={{header|J}}==
'''Solution''':<langsyntaxhighlight lang="j"> ef =: [: (}.~ 0={.) [: (, r2ef)/ 0 1 #: x:
r2ef =: (<(<0);0) { ((] , -) >:@:<.&.%)^:((~:<.)@:%)@:{:^:a:</langsyntaxhighlight>
'''Examples''' (''required''):<langsyntaxhighlight lang="j"> (; ef)&> 43r48 5r121 2014r59
+-------+--------------------------------------------------------------+
|43r48 |1r2 1r3 1r16 |
Line 555 ⟶ 1,384:
+-------+--------------------------------------------------------------+
|2014r59|34 1r8 1r95 1r14947 1r670223480 |
+-------+--------------------------------------------------------------+</langsyntaxhighlight>
 
'''Examples''' (''extended''):<langsyntaxhighlight lang="j"> NB. ef for all 1- and 2-digit fractions
EF2 =: ef :: _1:&.> (</~ * %/~) i. 10^2x
 
Line 622 ⟶ 1,451:
52971354428695554831016616883788904614906129646105943223862160217972480951002477
21274970802584016949299731051848322146227856796515503684655248210628598374099075
38269572622296774545103747438431266995525592705 </langsyntaxhighlight>
 
=={{header|Java}}==
{{trans|Kotlin}}
{{works with|Java|9}}
<langsyntaxhighlight Javalang="java">import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.MathContext;
Line 837 ⟶ 1,666:
}
}
}</langsyntaxhighlight>
{{out}}
<pre>43/48 -> 1/2 + 1/3 + 1/16
Line 858 ⟶ 1,687:
{{works with|Julia|0.6}}
 
<langsyntaxhighlight lang="julia">struct EgyptianFraction{T<:Integer} <: Real
int::T
frac::NTuple{N,Rational{T}} where N
Line 923 ⟶ 1,752:
frlenmax, lenmax, frdenmax, denmax = task(fr)
println("Longest fraction, with length $lenmax: \n", Rational(frlenmax), "\n = ", frlenmax)
println("Fraction with greatest denominator\n(that is $denmax):\n", Rational(frdenmax), "\n = ", frdenmax)</langsyntaxhighlight>
 
{{out}}
Line 959 ⟶ 1,788:
=={{header|Kotlin}}==
As the JDK lacks a fraction or rational class, I've included a basic one in the program.
<langsyntaxhighlight lang="scala">// version 1.2.10
 
import java.math.BigInteger
Line 1,126 ⟶ 1,955:
println(" fraction(s) with this denominator : $maxDenFracs")
}
}</langsyntaxhighlight>
 
{{out}}
Line 1,147 ⟶ 1,976:
</pre>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<langsyntaxhighlight Mathematicalang="mathematica">frac[n_] /; IntegerQ[1/n] := frac[n] = {n};
frac[n_] :=
frac[n] =
Line 1,169 ⟶ 1,998:
fracs = Flatten[Table[frac[p/q], {q, 999}, {p, q}], 1];
Print[disp[MaximalBy[fracs, Length@*Union][[1]]]];
Print[disp[MaximalBy[fracs, Denominator@*Last][[1]]]];</langsyntaxhighlight>
{{out}}
<pre>1/2 + 1/3 + 1/16 = 43/48
Line 1,181 ⟶ 2,010:
=={{header|Microsoft Small Basic}}==
Small Basic but large (not huge) integers.
<langsyntaxhighlight lang="smallbasic">'Egyptian fractions - 26/07/2018
xx=2014
yy=59
Line 1,234 ⟶ 2,063:
EndWhile
ret=wx
EndSub </langsyntaxhighlight>
{{out}}
43/48=1/2+1/3
5/121=1/25+1/757+1/763309+1/873960180913+1/1527612795642093418846225
2014/59=(34)+1/8+1/95+1/14947+1/670223480
 
=={{header|Nim}}==
{{trans|Go}}
{{libheader|bignum}}
<syntaxhighlight lang="nim">import strformat, strutils
import bignum
 
let
Zero = newInt(0)
One = newInt(1)
 
#---------------------------------------------------------------------------------------------------
 
proc toEgyptianrecursive(rat: Rat; fracs: seq[Rat]): seq[Rat] =
 
if rat.isZero: return fracs
 
let iquo = cdiv(rat.denom, rat.num)
let rquo = newRat(1, iquo)
result = fracs & rquo
let num2 = cmod(-rat.denom, rat.num)
if num2 < Zero:
num2 += rat.num
let denom2 = rat.denom * iquo
let f = newRat(num2, denom2)
if f.num == One:
result.add(f)
else:
result = f.toEgyptianrecursive(result)
 
#---------------------------------------------------------------------------------------------------
 
proc toEgyptian(rat: Rat): seq[Rat] =
 
if rat.num.isZero: return @[rat]
 
if abs(rat.num) >= rat.denom:
let iquo = rat.num div rat.denom
let rquo = newRat(iquo, 1)
let rrem = rat - rquo
result = rrem.toEgyptianrecursive(@[rquo])
else:
result = rat.toEgyptianrecursive(@[])
 
#———————————————————————————————————————————————————————————————————————————————————————————————————
 
for frac in [newRat(43, 48), newRat(5, 121), newRat(2014, 59)]:
let list = frac.toEgyptian()
if list[0].denom == One:
let first = fmt"[{list[0].num}]"
let rest = list[1..^1].join(" + ")
echo fmt"{frac} -> {first} + {rest}"
else:
let all = list.join(" + ")
echo fmt"{frac} -> {all}"
 
for r in [98, 998]:
if r == 98:
echo "\nFor proper fractions with 1 or 2 digits:"
else:
echo "\nFor proper fractions with 1, 2 or 3 digits:"
 
var maxSize = 0
var maxSizeFracs: seq[Rat]
var maxDen = Zero
var maxDenFracs: seq[Rat]
var sieve = newSeq[seq[bool]](r + 1) # To eliminate duplicates.
 
for item in sieve.mitems: item.setLen(r + 2)
for i in 1..r:
for j in (i + 1)..(r + 1):
if sieve[i][j]: continue
 
let f = newRat(i, j)
let list = f.toEgyptian()
let listSize = list.len
if listSize > maxSize:
maxSize = listSize
maxSizeFracs.setLen(0)
maxSizeFracs.add(f)
elif listSize == maxSize:
maxSizeFracs.add(f)
 
let listDen = list[^1].denom()
if listDen > maxDen:
maxDen = listDen
maxDenFracs.setLen(0)
maxDenFracs.add(f)
elif listDen == maxDen:
maxDenFracs.add(f)
 
if i < r div 2:
var k = 2
while j * k <= r + 1:
sieve[i * k][j * k] = true
inc k
 
echo fmt" largest number of items = {maxSize}"
echo fmt" fraction(s) with this number : {maxSizeFracs.join("", "")}"
let md = $maxDen
echo fmt" largest denominator = {md.len} digits, {md[0..19]}...{md[^20..^1]}"
echo fmt" fraction(s) with this denominator : {maxDenFracs.join("", "")}"</syntaxhighlight>
 
{{out}}
<pre>43/48 -> 1/2 + 1/3 + 1/16
5/121 -> 1/25 + 1/757 + 1/763309 + 1/873960180913 + 1/1527612795642093418846225
2014/59 -> [34] + 1/8 + 1/95 + 1/14947 + 1/670223480
 
For proper fractions with 1 or 2 digits:
largest number of items = 8
fraction(s) with this number : 8/97, 44/53
largest denominator = 150 digits, 57950458706754280171...62011424993909789665
fraction(s) with this denominator : 8/97
 
For proper fractions with 1, 2 or 3 digits:
largest number of items = 13
fraction(s) with this number : 529/914, 641/796
largest denominator = 2847 digits, 83901882683345018663...38431266995525592705
fraction(s) with this denominator : 36/457, 529/914</pre>
 
=={{header|PARI/GP}}==
<langsyntaxhighlight lang="parigp">
efrac(f)=my(v=List());while(f,my(x=numerator(f),y=denominator(f));listput(v,ceil(y/x));f=(-y)%x/y/v[#v]);Vec(v);
show(f)=my(n=f\1,v=efrac(f-n)); print1(f" = ["n"; "v[1]); for(i=2,#v,print1(", "v[i])); print("]");
Line 1,249 ⟶ 2,197:
best(99)
best(999)
</syntaxhighlight>
</lang>
{{out}}
<pre>43/48 = [0; 2, 3, 16]
Line 1,263 ⟶ 2,211:
Most terms is 529/914 with 13
Biggest denominator is 36/457 with 839...705</pre>
 
=={{header|Perl}}==
<langsyntaxhighlight lang="perl">use strict;
use warnings;
use bigint;
Line 1,299 ⟶ 2,248:
printf "\nEgyptian Fraction Representation of " . $nrI . "/" . $deI . " is: \n\n";
isEgyption($nrI,$deI);
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,305 ⟶ 2,254:
34 + 1/8 + 1/95 + 1/14947 + 1/670223480
</pre>
=={{header|Perl 6}}==
<lang perl6>role Egyptian {
method gist {
join ' + ',
("[{self.floor}]" if self.abs >= 1),
map {"1/$_"}, self.denominators;
}
method denominators {
my ($x, $y) = self.nude;
$x %= $y;
my @denom = gather ($x, $y) = -$y % $x, $y * take ($y / $x).ceiling
while $x;
}
}
 
say .nude.join('/'), " = ", $_ but Egyptian for 43/48, 5/121, 2014/59;
 
my @sample = map { $_ => .denominators },
grep * < 1,
map {$_ but Egyptian},
(2 .. 99 X/ 2 .. 99);
 
say .key.nude.join("/"),
" has max denominator, namely ",
.value.max
given max :by(*.value.max), @sample;
 
say .key.nude.join("/"),
" has max number of denominators, namely ",
.value.elems
given max :by(*.value.elems), @sample;</lang>
{{out}}
<pre>43/48 = 1/2 + 1/3 + 1/16
5/121 = 1/25 + 1/757 + 1/763309 + 1/873960180913 + 1/1527612795642093418846225
2014/59 = [34] + 1/8 + 1/95 + 1/14947 + 1/670223480
8/97 has max denominator, namely 579504587067542801713103191859918608251030291952195423583529357653899418686342360361798689053273749372615043661810228371898539583862011424993909789665
8/97 has max number of denominators, namely 8</pre>
 
Because the harmonic series diverges (albeit very slowly), it is possible to write even improper fractions as a sum of distinct unit fractions. Here is a code to do that:
 
<lang perl6>role Egyptian {
method gist { join ' + ', map {"1/$_"}, self.list }
method list {
my $sum = 0;
gather for 2 .. * {
last if $sum == self;
$sum += 1 / .take unless $sum + 1 / $_ > self;
}
}
}
say 5/4 but Egyptian;</lang>
{{out}}
<pre>1/2 + 1/3 + 1/4 + 1/6</pre>
 
The list of terms grows exponentially with the value of the fraction, though.
 
=={{header|Phix}}==
{{trans|tcl}}
{{libheader|bigatomPhix/mpfr}}
The sieve copied from Go
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>include builtins\bigatom.e
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
 
<span style="color: #008080;">include</span> <span style="color: #004080;">mpfr</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
function egyptian(integer num, denom)
<span style="color: #008080;">function</span> <span style="color: #000000;">egyptian</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">num</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">denom</span><span style="color: #0000FF;">)</span>
bigatom n = ba_new(num),
<span style="color: #004080;">mpz</span> <span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpz_init</span><span style="color: #0000FF;">(</span><span style="color: #000000;">num</span><span style="color: #0000FF;">),</span>
d = ba_new(denom)
<span style="color: #000000;">d</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpz_init</span><span style="color: #0000FF;">(</span><span style="color: #000000;">denom</span><span style="color: #0000FF;">),</span>
sequence result = {}
<span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpz_init</span><span style="color: #0000FF;">()</span>
while n!=BA_ZERO do
<span style="color: #004080;">sequence</span> <span style="color: #000000;">result</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
bigatom t = ba_ceil(ba_divide(d,n))
<span style="color: #008080;">while</span> <span style="color: #7060A8;">mpz_cmp_si</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">do</span>
result = append(result,t)
<span style="color: #7060A8;">mpz_cdiv_q</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">d</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
n = ba_mod(ba_sub(BA_ZERO,d),n)
<span style="color: #000000;">result</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">result</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"1/"</span><span style="color: #0000FF;">&</span><span style="color: #7060A8;">mpz_get_str</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">))</span>
d = ba_multiply(d,t)
<span style="color: #7060A8;">mpz_neg</span><span style="color: #0000FF;">(</span><span style="color: #000000;">d</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span><span style="color: #0000FF;">)</span>
end while
<span style="color: #7060A8;">mpz_mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
return result
<span style="color: #7060A8;">mpz_neg</span><span style="color: #0000FF;">(</span><span style="color: #000000;">d</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span><span style="color: #0000FF;">)</span>
end function
<span style="color: #7060A8;">mpz_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">d</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span><span style="color: #0000FF;">,</span><span style="color: #000000;">t</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
procedure efrac(integer num, denom)
<span style="color: #0000FF;">{</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpz_free</span><span style="color: #0000FF;">({</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span><span style="color: #0000FF;">})</span>
string prefix = ""
<span style="color: #008080;">return</span> <span style="color: #000000;">result</span>
if num>=denom then
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
integer whole = floor(num/denom)
num -= whole*denom
<span style="color: #008080;">procedure</span> <span style="color: #000000;">efrac</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">num</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">denom</span><span style="color: #0000FF;">)</span>
prefix = sprintf("[%d] + ",whole)
<span style="color: #004080;">string</span> <span style="color: #000000;">fraction</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%d/%d"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">num</span><span style="color: #0000FF;">,</span><span style="color: #000000;">denom</span><span style="color: #0000FF;">}),</span>
end if
<span style="color: #000000;">prefix</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span>
sequence s = egyptian(num, denom)
<span style="color: #008080;">if</span> <span style="color: #000000;">num</span><span style="color: #0000FF;">>=</span><span style="color: #000000;">denom</span> <span style="color: #008080;">then</span>
for i=1 to length(s) do s[i] = ba_sprintf("1/%B",s[i]) end for
<span style="color: #004080;">integer</span> <span style="color: #000000;">whole</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">num</span><span style="color: #0000FF;">/</span><span style="color: #000000;">denom</span><span style="color: #0000FF;">)</span>
printf(1,"%d/%d -> %s\n",{num, denom, prefix & join(s," + ")})
<span style="color: #000000;">num</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">whole</span><span style="color: #0000FF;">*</span><span style="color: #000000;">denom</span>
end procedure
<span style="color: #000000;">prefix</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"[%d] + "</span><span style="color: #0000FF;">,</span><span style="color: #000000;">whole</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
efrac(43,48)
<span style="color: #004080;">string</span> <span style="color: #000000;">e</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #000000;">egyptian</span><span style="color: #0000FF;">(</span><span style="color: #000000;">num</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">denom</span><span style="color: #0000FF;">),</span><span style="color: #008000;">" + "</span><span style="color: #0000FF;">)</span>
efrac(5,121)
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%s -&gt; %s%s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">fraction</span><span style="color: #0000FF;">,</span><span style="color: #000000;">prefix</span><span style="color: #0000FF;">,</span><span style="color: #000000;">e</span><span style="color: #0000FF;">})</span>
efrac(2014,59)
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
 
integer maxt = 0
<span style="color: #000000;">efrac</span><span style="color: #0000FF;">(</span><span style="color: #000000;">43</span><span style="color: #0000FF;">,</span><span style="color: #000000;">48</span><span style="color: #0000FF;">)</span>
string maxts = ""
<span style="color: #000000;">efrac</span><span style="color: #0000FF;">(</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">121</span><span style="color: #0000FF;">)</span>
integer maxd = 0
<span style="color: #000000;">efrac</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2014</span><span style="color: #0000FF;">,</span><span style="color: #000000;">59</span><span style="color: #0000FF;">)</span>
string maxds = ""
bigatom maxda
<span style="color: #004080;">integer</span> <span style="color: #000000;">maxt</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">maxd</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
for r=98 to 998 by 900 do -- (iterates just twice!)
<span style="color: #004080;">string</span> <span style="color: #000000;">maxts</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span><span style="color: #0000FF;">,</span>
sequence sieve = repeat(repeat(false,r+1),r) -- to eliminate duplicates
<span style="color: #000000;">maxds</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span><span style="color: #0000FF;">,</span>
for n=1 to r do
<span style="color: #000000;">maxda</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span>
for d=n+1 to r+1 do
if sieve[n][d]=false then
<span style="color: #008080;">for</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">=</span><span style="color: #000000;">98</span> <span style="color: #008080;">to</span> <span style="color: #000000;">998</span> <span style="color: #008080;">by</span> <span style="color: #000000;">900</span> <span style="color: #008080;">do</span> <span style="color: #000080;font-style:italic;">-- (iterates just twice!)</span>
string term = sprintf("%d/%d",{n,d})
<span style="color: #004080;">sequence</span> <span style="color: #000000;">sieve</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #004600;">false</span><span style="color: #0000FF;">,</span><span style="color: #000000;">r</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">),</span><span style="color: #000000;">r</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- to eliminate duplicates</span>
sequence terms = egyptian(n,d)
<span style="color: #008080;">for</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">r</span> <span style="color: #008080;">do</span>
integer nterms = length(terms)
<span style="color: #008080;">for</span> <span style="color: #000000;">d</span><span style="color: #0000FF;">=</span><span style="color: #000000;">n</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
if nterms>maxt then
<span style="color: #008080;">if</span> <span style="color: #000000;">sieve</span><span style="color: #0000FF;">[</span><span style="color: #000000;">n</span><span style="color: #0000FF;">][</span><span style="color: #000000;">d</span><span style="color: #0000FF;">]=</span><span style="color: #004600;">false</span> <span style="color: #008080;">then</span>
maxt = nterms
<span style="color: #004080;">string</span> <span style="color: #000000;">term</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%d/%d"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span><span style="color: #0000FF;">})</span>
maxts = term
<span style="color: #004080;">sequence</span> <span style="color: #000000;">terms</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">egyptian</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span><span style="color: #0000FF;">)</span>
elsif nterms=maxt then
<span style="color: #004080;">integer</span> <span style="color: #000000;">nterms</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">terms</span><span style="color: #0000FF;">)</span>
maxts &= ", " & term
<span style="color: #008080;">if</span> <span style="color: #000000;">nterms</span><span style="color: #0000FF;">></span><span style="color: #000000;">maxt</span> <span style="color: #008080;">then</span>
end if
<span style="color: #000000;">maxt</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">nterms</span>
integer mlen = length(ba_sprintf("%B",terms[$]))
<span style="color: #000000;">maxts</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">term</span>
if mlen>maxd then
<span style="color: #008080;">elsif</span> <span style="color: #000000;">nterms</span><span style="color: #0000FF;">=</span><span style="color: #000000;">maxt</span> <span style="color: #008080;">then</span>
maxd = mlen
<span style="color: #000000;">maxts</span> <span style="color: #0000FF;">&=</span> <span style="color: #008000;">", "</span> <span style="color: #0000FF;">&</span> <span style="color: #000000;">term</span>
maxds = term
<span style="color: #008080;">end</span> maxda<span style="color: terms[$]#008080;">if</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">mlen</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">terms</span><span style="color: #0000FF;">[$])-</span><span style="color: #000000;">2</span>
elsif mlen=maxd then
<span style="color: #008080;">if</span> <span style="color: #000000;">mlen</span><span style="color: #0000FF;">></span><span style="color: #000000;">maxd</span> <span style="color: #008080;">then</span>
maxds &= ", " & term
<span style="color: #000000;">maxd</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">mlen</span>
end if
<span style="color: #000000;">maxds</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">term</span>
if n < r/2 then
<span style="color: #000000;">maxda</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">terms</span><span style="color: #0000FF;">[$]</span>
for k=2 to 9999 do
<span style="color: #008080;">elsif</span> <span style="color: #000000;">mlen</span><span style="color: #0000FF;">=</span><span style="color: #000000;">maxd</span> <span style="color: #008080;">then</span>
if d*k > r+1 then exit end if
<span style="color: #000000;">maxds</span> <span style="color: #0000FF;">&=</span> <span style="color: #008000;">", "</span> <span style="color: #0000FF;">&</span> <span style="color: #000000;">term</span>
sieve[n*k][d*k] = true
<span style="color: #008080;">end</span> <span style="color: for#008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">n</span><span style="color: #0000FF;"><</span><span style="color: #000000;">r</span><span style="color: #0000FF;">/</span><span style="color: #000000;">2</span> <span style="color: #008080;">then</span>
end if
<span style="color: #008080;">for</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span> <span style="color: #008080;">to</span> <span style="color: #000000;">9999</span> <span style="color: #008080;">do</span>
end if
<span style="color: #008080;">if</span> <span style="color: #000000;">d</span><span style="color: #0000FF;">*</span><span style="color: #000000;">k</span> <span style="color: #0000FF;">></span> <span style="color: #000000;">r</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end for
<span style="color: #000000;">sieve</span><span style="color: #0000FF;">[</span><span style="color: #000000;">n</span><span style="color: #0000FF;">*</span><span style="color: #000000;">k</span><span style="color: #0000FF;">][</span><span style="color: #000000;">d</span><span style="color: #0000FF;">*</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">true</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
printf(1,"\n")
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
printf(1,"for proper fractions with 1 to %d digits\n",{length(sprint(r))})
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
printf(1,"Largest number of terms is %d for %s\n",{maxt,maxts})
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
string m_str = ba_sprintf("%B",maxda)
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
m_str[6..-6]="..."
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\nfor proper fractions with 1 to %d digits\n"</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">sprint</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r</span><span style="color: #0000FF;">))})</span>
printf(1,"Largest size for denominator is %d digits (%s) for %s\n",{maxd,m_str,maxds})
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Largest number of terms is %d for %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">maxt</span><span style="color: #0000FF;">,</span><span style="color: #000000;">maxts</span><span style="color: #0000FF;">})</span>
end for</lang>
<span style="color: #000000;">maxda</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">maxda</span><span style="color: #0000FF;">[</span><span style="color: #000000;">3</span><span style="color: #0000FF;">..$]</span> <span style="color: #000080;font-style:italic;">-- (strip the "1/")</span>
<span style="color: #000000;">maxda</span><span style="color: #0000FF;">[</span><span style="color: #000000;">6</span><span style="color: #0000FF;">..-</span><span style="color: #000000;">6</span><span style="color: #0000FF;">]=</span><span style="color: #008000;">"..."</span> <span style="color: #000080;font-style:italic;">-- (show only first/last 5 digits)</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Largest size for denominator is %d digits (%s) for %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">maxd</span><span style="color: #0000FF;">,</span><span style="color: #000000;">maxda</span><span style="color: #0000FF;">,</span><span style="color: #000000;">maxds</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
43/48 -> 1/2 + 1/3 + 1/16
5/121 -> 1/25 + 1/757 + 1/763309 + 1/873960180913 + 1/1527612795642093418846225
82014/59 -> [34] + 1/8 + 1/95 + 1/14947 + 1/670223480
 
for proper fractions with 1 to 2 digits
Line 1,454 ⟶ 2,352:
Largest number of terms is 13 for 529/914, 641/796
Largest size for denominator is 2847 digits (83901...92705) for 36/457, 529/914
</pre>
 
=={{header|Prolog}}==
{{works with|SWI Prolog}}
<syntaxhighlight lang="prolog">count_digits(Number, Count):-
atom_number(A, Number),
atom_length(A, Count).
 
integer_to_atom(Number, Atom):-
atom_number(A, Number),
atom_length(A, Count),
(Count =< 20 ->
Atom = A
;
sub_atom(A, 0, 10, _, A1),
P is Count - 10,
sub_atom(A, P, 10, _, A2),
atom_concat(A1, '...', A3),
atom_concat(A3, A2, Atom)
).
 
egyptian(0, _, []):- !.
egyptian(X, Y, [Z|E]):-
Z is (Y + X - 1)//X,
X1 is -Y mod X,
Y1 is Y * Z,
egyptian(X1, Y1, E).
 
print_egyptian([]):- !.
print_egyptian([N|List]):-
integer_to_atom(N, A),
write(1/A),
(List = [] -> true; write(' + ')),
print_egyptian(List).
 
print_egyptian(X, Y):-
writef('Egyptian fraction for %t/%t: ', [X, Y]),
(X > Y ->
N is X//Y,
writef('[%t] ', [N]),
X1 is X mod Y
;
X1 = X
),
egyptian(X1, Y, E),
print_egyptian(E),
nl.
 
max_terms_and_denominator1(D, Max_terms, Max_denom, Max_terms1, Max_denom1):-
max_terms_and_denominator1(D, 1, Max_terms, Max_denom, Max_terms1, Max_denom1).
 
max_terms_and_denominator1(D, D, Max_terms, Max_denom, Max_terms, Max_denom):- !.
max_terms_and_denominator1(D, N, Max_terms, Max_denom, Max_terms1, Max_denom1):-
Max_terms1 = f(_, _, _, Len1),
Max_denom1 = f(_, _, _, Max1),
egyptian(N, D, E),
length(E, Len),
last(E, Max),
(Len > Len1 ->
Max_terms2 = f(N, D, E, Len)
;
Max_terms2 = Max_terms1
),
(Max > Max1 ->
Max_denom2 = f(N, D, E, Max)
;
Max_denom2 = Max_denom1
),
N1 is N + 1,
max_terms_and_denominator1(D, N1, Max_terms, Max_denom, Max_terms2, Max_denom2).
 
max_terms_and_denominator(N, Max_terms, Max_denom):-
max_terms_and_denominator(N, 1, Max_terms, Max_denom, f(0, 0, [], 0),
f(0, 0, [], 0)).
 
max_terms_and_denominator(N, N, Max_terms, Max_denom, Max_terms, Max_denom):-!.
max_terms_and_denominator(N, N1, Max_terms, Max_denom, Max_terms1, Max_denom1):-
max_terms_and_denominator1(N1, Max_terms2, Max_denom2, Max_terms1, Max_denom1),
N2 is N1 + 1,
max_terms_and_denominator(N, N2, Max_terms, Max_denom, Max_terms2, Max_denom2).
 
show_max_terms_and_denominator(N):-
writef('Proper fractions with most terms and largest denominator, limit = %t:\n', [N]),
max_terms_and_denominator(N, f(N_max_terms, D_max_terms, E_max_terms, Len),
f(N_max_denom, D_max_denom, E_max_denom, Max)),
writef('Most terms (%t): %t/%t = ', [Len, N_max_terms, D_max_terms]),
print_egyptian(E_max_terms),
nl,
count_digits(Max, Digits),
writef('Largest denominator (%t digits): %t/%t = ', [Digits, N_max_denom, D_max_denom]),
print_egyptian(E_max_denom),
nl.
 
main:-
print_egyptian(43, 48),
print_egyptian(5, 121),
print_egyptian(2014, 59),
nl,
show_max_terms_and_denominator(100),
nl,
show_max_terms_and_denominator(1000).</syntaxhighlight>
 
{{out}}
<pre>
Egyptian fraction for 43/48: 1/2 + 1/3 + 1/16
Egyptian fraction for 5/121: 1/25 + 1/757 + 1/763309 + 1/873960180913 + 1/1527612795...3418846225
Egyptian fraction for 2014/59: [34] 1/8 + 1/95 + 1/14947 + 1/670223480
 
Proper fractions with most terms and largest denominator, limit = 100:
Most terms (8): 44/53 = 1/2 + 1/4 + 1/13 + 1/307 + 1/120871 + 1/20453597227 + 1/6972493991...6783218655 + 1/1458470173...7836808420
Largest denominator (150 digits): 8/97 = 1/13 + 1/181 + 1/38041 + 1/1736503177 + 1/3769304102927363485 + 1/1894353789...8154430149 + 1/5382864419...4225813153 + 1/5795045870...3909789665
 
Proper fractions with most terms and largest denominator, limit = 1000:
Most terms (13): 641/796 = 1/2 + 1/4 + 1/19 + 1/379 + 1/159223 + 1/28520799973 + 1/9296411783...1338400861 + 1/1008271507...4174730681 + 1/1219933718...8484537833 + 1/1860297848...1025882029 + 1/4614277444...8874327093 + 1/3193733450...1456418881 + 1/2039986670...2410165441
Largest denominator (2847 digits): 36/457 = 1/13 + 1/541 + 1/321409 + 1/114781617793 + 1/1482167225...0844346913 + 1/2510651068...4290086881 + 1/7353930250...3326272641 + 1/6489634815...7391865217 + 1/5264420004...5476206145 + 1/3695215730...1238141889 + 1/2048192894...4706590593 + 1/8390188268...5525592705
</pre>
 
=={{header|Python}}==
===Procedural===
<lang python>from fractions import Fraction
<syntaxhighlight lang="python">from fractions import Fraction
from math import ceil
 
Line 1,494 ⟶ 2,508:
dstr = str(denommax[0])
print('Denominator max is %r with %i digits %s...%s' %
(denommax[1], len(dstr), dstr[:5], dstr[-5:]))</langsyntaxhighlight>
 
{{out}}
Line 1,502 ⟶ 2,516:
Term max is 97/53 with 9 terms
Denominator max is 8/97 with 150 digits 57950...89665</pre>
 
===Composition of pure functions===
The derivation of a sequence of unit fractions from a single fraction is a classic case of an anamorphism or '''unfold''' abstraction – dual to a fold or catamorphism. Rather than reducing, collapsing or summarizing a structure '''to''' a single value, it builds a structure '''from''' a single value.
 
See the '''unfoldr''' function below:
{{Works with|Python|3.7}}
<syntaxhighlight lang="python">'''Egyptian fractions'''
 
from fractions import Fraction
from functools import reduce
from operator import neg
 
 
# eqyptianFraction :: Ratio Int -> Ratio Int
def eqyptianFraction(nd):
'''The rational number nd as a sum
of the series of unit fractions
obtained by application of the
greedy algorithm.'''
def go(x):
n, d = x.numerator, x.denominator
r = 1 + d // n if n else None
return Just((0, x) if 1 == n else (
(fr(n % d, d), fr(n // d, 1)) if n > d else (
fr(-d % n, d * r), fr(1, r)
)
)) if n else Nothing()
fr = Fraction
f = unfoldr(go)
return list(map(neg, f(-nd))) if 0 > nd else f(nd)
 
 
# TESTS ---------------------------------------------------
 
# maxEqyptianFraction :: Int -> (Ratio Int -> a)
# -> (Ratio Int, a)
def maxEqyptianFraction(nDigits):
'''An Egyptian Fraction, representing a
proper fraction with numerators and
denominators of up to n digits each,
which returns a maximal value for the
supplied function f.'''
 
# maxVals :: ([Ratio Int], a) -> (Ratio Int, a)
# -> ([Ratio Int], a)
def maxima(xsv, ndfx):
xs, v = xsv
nd, fx = ndfx
return ([nd], fx) if fx > v else (
xs + [nd], v
) if fx == v and nd not in xs else xsv
 
# go :: (Ratio Int -> a) -> ([Ratio Int], a)
def go(f):
iLast = int(nDigits * '9')
fs, mx = reduce(
maxima, [
(nd, f(eqyptianFraction(nd))) for nd in [
Fraction(n, d)
for n in enumFromTo(1)(iLast)
for d in enumFromTo(1 + n)(iLast)
]
],
([], 0)
)
return f.__name__ + ' -> [' + ', '.join(
map(str, fs)
) + '] -> ' + str(mx)
return lambda f: go(f)
 
 
# main :: IO ()
def main():
'''Tests'''
 
ef = eqyptianFraction
fr = Fraction
 
print('Three values as Eqyptian fractions:')
print('\n'.join([
str(fr(*nd)) + ' -> ' + ' + '.join(map(str, ef(fr(*nd))))
for nd in [(43, 48), (5, 121), (2014, 59)]
]))
 
# maxDenominator :: [Ratio Int] -> Int
def maxDenominator(ef):
return max(map(lambda nd: nd.denominator, ef))
 
# maxTermCount :: [Ratio Int] -> Int
def maxTermCount(ef):
return len(ef)
 
for i in [1, 2, 3]:
print(
'\nMaxima for proper fractions with up to ' + (
str(i) + ' digit(s):'
)
)
for f in [maxTermCount, maxDenominator]:
print(maxEqyptianFraction(i)(f))
 
 
# GENERIC -------------------------------------------------
 
 
# Just :: a -> Maybe a
def Just(x):
'''Constructor for an inhabited Maybe (option type) value.'''
return {'type': 'Maybe', 'Nothing': False, 'Just': x}
 
 
# Nothing :: Maybe a
def Nothing():
'''Constructor for an empty Maybe (option type) value.'''
return {'type': 'Maybe', 'Nothing': True}
 
 
# enumFromTo :: (Int, Int) -> [Int]
def enumFromTo(m):
'''Integer enumeration from m to n.'''
return lambda n: list(range(m, 1 + n))
 
 
# unfoldr :: (b -> Maybe (b, a)) -> b -> [a]
def unfoldr(f):
'''Dual to reduce or foldr.
Where catamorphism reduces a list to a summary value,
the anamorphic unfoldr builds a list from a seed value.
As long as f returns Just(a, b), a is prepended to the list,
and the residual b is used as the argument for the next
application of f.
When f returns Nothing, the completed list is returned.'''
def go(xr):
mb = f(xr[0])
if mb.get('Nothing'):
return []
else:
y, r = mb.get('Just')
return [r] + go((y, r))
 
return lambda x: go((x, x))
 
 
# MAIN ---
if __name__ == '__main__':
main()</syntaxhighlight>
{{Out}}
<pre>Three values as Eqyptian fractions:
43/48 -> 1/2 + 1/3 + 1/16
5/121 -> 1/25 + 1/757 + 1/763309 + 1/873960180913 + 1/1527612795642093418846225
2014/59 -> 34 + 1/8 + 1/95 + 1/14947 + 1/670223480
 
Maxima for proper fractions with up to 1 digit(s):
maxTermCount -> [3/7, 4/5, 5/7, 6/7, 7/8, 7/9, 8/9] -> 3
maxDenominator -> [3/7] -> 231
 
Maxima for proper fractions with up to 2 digit(s):
maxTermCount -> [8/97, 44/53] -> 8
maxDenominator -> [8/97] -> 579504587067542801713103191859918608251030291952195423583529357653899418686342360361798689053273749372615043661810228371898539583862011424993909789665
 
Maxima for proper fractions with up to 3 digit(s):
maxTermCount -> [529/914, 641/796] -> 13
maxDenominator -> [36/457, 529/914] -> 839018826833450186636781520007011999269820404906753180244759299287837378895397605613261469995626498719289835112392530430840514102146998625666594756995273418015600023494049208108894185781774002683063204252356172520941088783702738286944210460710059319691268110283467445381026653628599765684739105388642310044785844902157076919003735231543781785073393176144167688252446541416466418608465458502997971425428342769433127784560570193376772878336217849260872114137931351960543608384244009505664253173875705234889570853924105640193619301332776989688248555027054395237907581951261868280899150574360164800187964167274323078311078867593844043149124596271281252530924719121766925749760855109100066731841478262812686642693395896229983745226277793055820609058348269152190083695704685769622011655159174272326647342695589818127126303038171968768650476413027459205291075571637957597356820188031655122749743652301268394542123970892422944335857917641636041892192547135178153602038877677614358281581103685526041329841496863410305888255234495015115912388514981113593387572720476744188169200130515719608747338810136728267784013352396910979904545913458536243327311977805126410065576961237640824852114328884086581542091492600312838425666927627674227053793897767395465326589843035773944346372949759909905561209334216847158156644884281300512699910530092870919061876615770708519243818676366245477462042294267674677954783726990349386117468071932874021023714524610740225814235147693954027910741673103980749749728106483987721602738673173009362802337092908847797499475895347112889339502928407808058670297722175686638678788738689803945574002805677250463286479363670076942509109589495377221095405979217163821481666646160815221224686562530536116613645305335922819524037829878961518170177968768364853399057357772141655622381280196908637031556436461404285930426436983658106288733881761514992109680298995922754466040011586713812553117621857109517258943846004179432521131844156242428351270188803919554398620084668514054504414062276012292497375238210886595006249453460414790147611422121782194848803348777061816460876697945418158442269512987729152441940326466631610424906158237288218706447963113019239557885486647314085357651895226117364760315394354624547919209138539180807829672545924239541758108877100331729470119526373928796447673951888289511964811633025369821156695934557103429921063387965046715070102916811976552584464153981214277622597308113449320462341683055200576571910241686615924531368198770946893858410058348221985603151428153382461711196734214085852523778422630907646235900752317571022131569421231196329080023952364788544301495422061066036911772385739659997665503832444529713544286955548310166168837889046149061296461059432238621602179724809510024772127497080258401694929973105184832214622785679651550368465524821062859837409907538269572622296774545103747438431266995525592705</pre>
 
=={{header|Racket}}==
 
<langsyntaxhighlight lang="racket">#lang racket
(define (real->egyptian-list R)
(define (inr r rv)
Line 1,553 ⟶ 2,730:
 
(module+ test (require tests/eli-tester)
(test (real->egyptian-list 43/48) => '(1/2 1/3 1/16)))</langsyntaxhighlight>
 
{{out}}
Line 1,619 ⟶ 2,796:
89823812369...]
1 test passed</pre>
 
=={{header|Raku}}==
(formerly Perl 6)
<syntaxhighlight lang="raku" line>role Egyptian {
method gist {
join ' + ',
("[{self.floor}]" if self.abs >= 1),
map {"1/$_"}, self.denominators;
}
method denominators {
my ($x, $y) = self.nude;
$x %= $y;
my @denom = gather ($x, $y) = -$y % $x, $y * take ($y / $x).ceiling
while $x;
}
}
 
say .nude.join('/'), " = ", $_ but Egyptian for 43/48, 5/121, 2014/59;
 
my @sample = map { $_ => .denominators },
grep * < 1,
map {$_ but Egyptian},
(2 .. 99 X/ 2 .. 99);
 
say .key.nude.join("/"),
" has max denominator, namely ",
.value.max
given max :by(*.value.max), @sample;
 
say .key.nude.join("/"),
" has max number of denominators, namely ",
.value.elems
given max :by(*.value.elems), @sample;</syntaxhighlight>
{{out}}
<pre>43/48 = 1/2 + 1/3 + 1/16
5/121 = 1/25 + 1/757 + 1/763309 + 1/873960180913 + 1/1527612795642093418846225
2014/59 = [34] + 1/8 + 1/95 + 1/14947 + 1/670223480
8/97 has max denominator, namely 579504587067542801713103191859918608251030291952195423583529357653899418686342360361798689053273749372615043661810228371898539583862011424993909789665
8/97 has max number of denominators, namely 8</pre>
 
Because the harmonic series diverges (albeit very slowly), it is possible to write even improper fractions as a sum of distinct unit fractions. Here is a code to do that:
 
<syntaxhighlight lang="raku" line>role Egyptian {
method gist { join ' + ', map {"1/$_"}, self.list }
method list {
my $sum = 0;
gather for 2 .. * {
last if $sum == self;
$sum += 1 / .take unless $sum + 1 / $_ > self;
}
}
}
say 5/4 but Egyptian;</syntaxhighlight>
{{out}}
<pre>1/2 + 1/3 + 1/4 + 1/6</pre>
 
The list of terms grows exponentially with the value of the fraction, though.
 
=={{header|REXX}}==
<langsyntaxhighlight lang="rexx">/*REXX program converts a fraction (can be improper) to an Egyptian fraction. */
parse arg fract '' -1 t; z=$egyptF(fract) /*compute the Egyptian fraction. */
if t\==. then say fract ' ───► ' z /*show Egyptian fraction from C.L.*/
Line 1,673 ⟶ 2,908:
gcd:procedure;$=;do i=1 for arg();$=$ arg(i);end;parse var $ x z .;if x=0 then x=z;x=abs(x);do j=2 to words($);y=abs(word($,j));if y=0 then iterate;do until _==0;_=x//y;x=y;y=_;end;end;return x
lcm:procedure;y=;do j=1 for arg();y=y arg(j);end;x=word(y,1);do k=2 to words(y);!=abs(word(y,k));if !=0 then return 0;x=x*!/gcd(x,!);end;return x
p: return word(arg(1),1)</langsyntaxhighlight>
'''output''' &nbsp; when the input used is: &nbsp; <tt> 43/48 </tt>
<pre>
Line 1,695 ⟶ 2,930:
 
Also, the same program is used for the 1-, 2-, and 3-digit extra credit task.
<langsyntaxhighlight lang="rexx">/*REXX pgm runs the EGYPTIAN program to find biggest denominator & # of terms.*/
parse arg top . /*get optional parameter from the C.L. */
if top=='' then top=99 /*Not specified? Then use the default.*/
Line 1,718 ⟶ 2,953:
say
say 'highest denominator' @ length(maxD) "digits for" bigD
if oTop>0 then say maxD /*stick a fork in it, we're all done. */</langsyntaxhighlight>
'''output''' &nbsp; for all 1- and 2-digit integers when using the default input:
<pre>
Line 1,730 ⟶ 2,965:
largest denominator in the Egyptian fractions is 2847 digits is for 36/457
</pre>
 
=={{header|RPL}}==
<code>GCD</code> is defined at [[Greatest common divisor#RPL|Greatest common divisor]]
{{works with|Halcyon Calc|4.2.7}}
{| class="wikitable" ≪
! RPL code
! Comment
|-
|
DUP IM LAST RE / CEIL
SWAP RE LAST IM DUP NEG ROT MOD
SWAP 3 PICK *
DUP2 <span style="color:blue">GCD</span> ROT OVER / ROT ROT / R→C
≫ '<span style="color:blue">SPLIT</span>' STO
DUP 3 EXGET SWAP 1 EXGET
'''IF''' DUP2 > '''THEN'''
SWAP OVER MOD LAST / IP SWAP ROT
'''ELSE''' 0 ROT ROT '''END'''
R→C
'''WHILE''' DUP RE '''REPEAT'''
<span style="color:blue">SPLIT</span>
"'1/" ROT →STR + "'" + STR→
ROT SWAP + SWAP
'''END'''
≫ '<span style="color:blue">EGYPF</span>' STO
|
<span style="color:blue">SPLIT</span> ''( (x1,y1) → n1 (x2,y2) ) ''
n1 = ceil(y1/x1)
x2 = mod(-y1,x1)
y2 = n1*y1
simplify x2/y2
<span style="color:blue">EGYPF</span> ''( 'x/y' → 'sum_of_Egyptian_fractions') ''
put x and y in stack
if x > y
first term of sum is x//y and x = mod(x,y)
else first term is 0
convert to complex to ease handling in stack
loop while x<sub>k</sub> ≠ 0
get n<sub>k</sub> and (x<sub>k</sub>, y<sub>k</sub>)
convert n<sub>k</sub> into '1/n<sub>k</sub>'
add '1/n<sub>k</sub>' to the sum
end loop
return sum
|}
'43/48' <span style="color:blue">EGYPF</span>
'5/121' <span style="color:blue">EGYPF</span>
'2014/59' <span style="color:blue">EGYPF</span>
{{out}}
<pre>
3: 'INV(2)+INV(3)+INV(16)'
2: 'INV(25)+INV(757)+INV(763309)+INV(873960180913)+INV(1.52761279564E+24)'
1: '34+INV(8)+INV(95)+INV(14947)+INV(670223480)'
</pre>
In algebraic expressions, RPL automatically replaces <code>1/n</code> by <code>INV(n)</code>
====Quest for the largest number of items for proper fractions 2.99/2..99====
≪ '1/1' 0
2 99 '''FOR''' d 2 d 1 - '''FOR''' n
"'" n →STR + "/" + d →STR + "'" + STR→
DUP <span style="color:blue">EGYPF</span> SIZE → f sf
≪ '''IF''' sf OVER > '''THEN''' DROP2 f sf '''END''' ≫
'''NEXT NEXT''' DROP
≫ '<span style="color:blue">TASK</span>'
{{out}}
<pre>
1: '44/53'
</pre>
Limited precision of basic RPL prevents from searching the largest denominator.
 
=={{header|Ruby}}==
{{trans|Python}}
<langsyntaxhighlight lang="ruby">def ef(fr)
ans = []
if fr >= 1
Line 1,765 ⟶ 3,072:
puts 'Term max is %s with %i terms' % [lenmax[1], lenmax[0]]
dstr = denommax[0].to_s
puts 'Denominator max is %s with %i digits' % [denommax[1], dstr.size], dstr</langsyntaxhighlight>
 
{{out}}
Line 1,776 ⟶ 3,083:
579504587067542801713103191859918608251030291952195423583529357653899418686342360361798689053273749372615043661810228371898539583862011424993909789665
</pre>
 
=={{header|Rust}}==
<syntaxhighlight lang="rust">
use num_bigint::BigInt;
use num_integer::Integer;
use num_traits::{One, Zero};
use std::fmt;
 
#[derive(Debug, Clone, PartialEq, PartialOrd)]
struct Rational {
nominator: BigInt,
denominator: BigInt,
}
 
impl Rational {
fn new(n: &BigInt, d: &BigInt) -> Rational {
assert!(!d.is_zero(), "denominator cannot be 0");
// simplify if possible
let c = n.gcd(d);
Rational {
nominator: n / &c,
denominator: d / &c,
}
}
 
fn is_proper(&self) -> bool {
self.nominator < self.denominator
}
fn to_egyptian(&self) -> Vec<Rational> {
let mut frac: Vec<Rational> = Vec::new();
 
let mut current: Rational;
if !self.is_proper() {
// input is grater than 1
// store the integer part
frac.push(Rational::new(
&self.nominator.div_floor(&self.denominator),
&One::one(),
));
 
// calculate the remainder
current = Rational::new(
&self.nominator.mod_floor(&self.denominator),
&self.denominator,
);
} else {
current = self.clone();
}
 
while !current.nominator.is_one() {
let div = current.denominator.div_ceil(&current.nominator);
 
// store the term
frac.push(Rational::new(&One::one(), &div));
 
current = Rational::new(
&(-&current.denominator).mod_floor(&current.nominator),
match current.denominator.checked_mul(&div).as_ref() {
Some(r) => r,
_ => break,
},
);
}
 
frac.push(current);
frac
}
}
 
impl fmt::Display for Rational {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if self.denominator.is_one() {
// for integers only display the integer part
write!(f, "{}", self.nominator)
} else {
write!(f, "{}/{}", self.nominator, self.denominator)
}
}
}
 
fn rational_vec_to_string(vec: Vec<Rational>) -> String {
let mut p = vec
.iter()
.fold(String::new(), |acc, num| (acc + &num.to_string() + ", "));
 
if p.len() > 1 {
p.truncate(p.len() - 2);
}
format!("[{}]", p)
}
 
fn run_max_searches(x: usize) {
// generate all proper fractions with 2 digits
let pairs = (1..x).flat_map(move |i| (i + 1..x).map(move |j| (i, j)));
 
let mut max_length = (0, Rational::new(&BigInt::from(1), &BigInt::from(1)));
let mut max_denom = (
Zero::zero(),
Rational::new(&BigInt::from(1), &BigInt::from(1)),
);
 
for (i, j) in pairs {
let e = Rational::new(&BigInt::from(i), &BigInt::from(j)).to_egyptian();
if e.len() > max_length.0 {
max_length = (e.len(), Rational::new(&BigInt::from(i), &BigInt::from(j)));
}
 
if e.last().unwrap().denominator > max_denom.0 {
max_denom = (
e.last().unwrap().denominator.clone(),
Rational::new(&BigInt::from(i), &BigInt::from(j)),
);
}
}
 
println!(
"Maximum length of terms is for {} with {} terms",
max_length.1, max_length.0
);
println!("{}", rational_vec_to_string(max_length.1.to_egyptian()));
 
println!(
"Maximum denominator is for {} with {} terms",
max_denom.1, max_denom.0
);
println!("{}", rational_vec_to_string(max_denom.1.to_egyptian()));
}
fn main() {
let tests = [
Rational::new(&BigInt::from(43), &BigInt::from(48)),
Rational::new(&BigInt::from(5), &BigInt::from(121)),
Rational::new(&BigInt::from(2014), &BigInt::from(59)),
];
 
for test in tests.iter() {
println!("{} -> {}", test, rational_vec_to_string(test.to_egyptian()));
}
 
run_max_searches(100);
run_max_searches(1000);
}
 
</syntaxhighlight>
{{out}}
<pre>
43/48 -> [1/2, 1/3, 1/16]
5/121 -> [1/25, 1/757, 1/763309, 1/873960180913, 1/1527612795642093418846225]
2014/59 -> [34, 1/8, 1/95, 1/14947, 1/670223480]
Maximum length of terms is for 8/97 with 8 terms
[1/13, 1/181, 1/38041, 1/1736503177, 1/3769304102927363485, 1/18943537893793408504192074528154430149, 1/538286441900380211365817285104907086347439746130226973253778132494225813153, 1/579504587067542801713103191859918608251030291952195423583529357653899418686342360361798689053273749372615043661810228371898539583862011424993909789665]
Maximum denominator is for 8/97 with 5795045870675428017131...3909789665 terms (150 digits)
[1/13, 1/181, 1/38041, 1/1736503177, 1/3769304102927363485, 1/18943537893793408504192074528154430149, 1/538286441900380211365817285104907086347439746130226973253778132494225813153, 1/5795045870675428017131...3909789665]
Maximum length of terms is for 529/914 with 13 terms:
[1/2, 1/13, 1/541, 1/321409, 1/114781617793, 1/14821672255960844346913, 1/251065106814993628596500876449600804290086881, 1/73539302503361520198362339236500915390885795679264404865887253300925727812630083326272641, 1/6489634815217096741...91865217, 1/52644200043...5476206145, 1/36952157309...38141889, 1/204819289476534...06590593, 1/83901882683...25592705]
Maximum denominator is for 36/457 with 83901882683...25592705 (2847 digits)
</pre>
 
=={{header|Scala}}==
{{trans|Java}}
<syntaxhighlight lang="scala">import scala.annotation.tailrec
import scala.collection.mutable
import scala.collection.mutable.{ArrayBuffer, ListBuffer}
 
abstract class Frac extends Comparable[Frac] {
val num: BigInt
val denom: BigInt
 
def toEgyptian: List[Frac] = {
if (num == 0) {
return List(this)
}
 
val fracs = new ArrayBuffer[Frac]
if (num.abs >= denom.abs) {
val div = Frac(num / denom, 1)
val rem = this - div
fracs += div
egyptian(rem.num, rem.denom, fracs)
} else {
egyptian(num, denom, fracs)
}
fracs.toList
}
 
@tailrec
private def egyptian(n: BigInt, d: BigInt, fracs: mutable.Buffer[Frac]): Unit = {
if (n == 0) {
return
}
val n2 = BigDecimal.apply(n)
val d2 = BigDecimal.apply(d)
val (divbd, rembd) = d2./%(n2)
var div = divbd.toBigInt()
if (rembd > 0) {
div = div + 1
}
fracs += Frac(1, div)
var n3 = -d % n
if (n3 < 0) {
n3 = n3 + n
}
val d3 = d * div
val f = Frac(n3, d3)
if (f.num == 1) {
fracs += f
return
}
egyptian(f.num, f.denom, fracs)
}
 
def unary_-(): Frac = {
Frac(-num, denom)
}
 
def +(rhs: Frac): Frac = {
Frac(
num * rhs.denom + rhs.num * denom,
denom * rhs.denom
)
}
 
def -(rhs: Frac): Frac = {
Frac(
num * rhs.denom - rhs.num * denom,
denom * rhs.denom
)
}
 
override def compareTo(rhs: Frac): Int = {
val ln = num * rhs.denom
val rn = rhs.num * denom
ln.compare(rn)
}
 
def canEqual(other: Any): Boolean = other.isInstanceOf[Frac]
 
override def equals(other: Any): Boolean = other match {
case that: Frac =>
(that canEqual this) &&
num == that.num &&
denom == that.denom
case _ => false
}
 
override def hashCode(): Int = {
val state = Seq(num, denom)
state.map(_.hashCode()).foldLeft(0)((a, b) => 31 * a + b)
}
 
override def toString: String = {
if (denom == 1) {
return s"$num"
}
s"$num/$denom"
}
}
 
object Frac {
def apply(n: BigInt, d: BigInt): Frac = {
if (d == 0) {
throw new IllegalArgumentException("Parameter d may not be zero.")
}
 
var nn = n
var dd = d
 
if (nn == 0) {
dd = 1
} else if (dd < 0) {
nn = -nn
dd = -dd
}
 
val g = nn.gcd(dd)
if (g > 0) {
nn /= g
dd /= g
}
 
new Frac {
val num: BigInt = nn
val denom: BigInt = dd
}
}
}
 
object EgyptianFractions {
def main(args: Array[String]): Unit = {
val fracs = List.apply(
Frac(43, 48),
Frac(5, 121),
Frac(2014, 59)
)
for (frac <- fracs) {
val list = frac.toEgyptian
val it = list.iterator
 
print(s"$frac -> ")
if (it.hasNext) {
val value = it.next()
if (value.denom == 1) {
print(s"[$value]")
} else {
print(value)
}
}
while (it.hasNext) {
val value = it.next()
print(s" + $value")
}
println()
}
 
for (r <- List(98, 998)) {
println()
if (r == 98) {
println("For proper fractions with 1 or 2 digits:")
} else {
println("For proper fractions with 1, 2 or 3 digits:")
}
 
var maxSize = 0
var maxSizeFracs = new ListBuffer[Frac]
var maxDen = BigInt(0)
var maxDenFracs = new ListBuffer[Frac]
val sieve = Array.ofDim[Boolean](r + 1, r + 2)
for (i <- 0 until r + 1) {
for (j <- i + 1 until r + 1) {
if (!sieve(i)(j)) {
val f = Frac(i, j)
val list = f.toEgyptian
val listSize = list.size
if (listSize > maxSize) {
maxSize = listSize
maxSizeFracs.clear()
maxSizeFracs += f
} else if (listSize == maxSize) {
maxSizeFracs += f
}
val listDen = list.last.denom
if (listDen > maxDen) {
maxDen = listDen
maxDenFracs.clear()
maxDenFracs += f
} else if (listDen == maxDen) {
maxDenFracs += f
}
if (i < r / 2) {
var k = 2
while (j * k <= r + 1) {
sieve(i * k)(j * k) = true
k = k + 1
}
}
}
}
}
println(s" largest number of items = $maxSize")
println(s"fraction(s) with this number : ${maxSizeFracs.toList}")
val md = maxDen.toString()
print(s" largest denominator = ${md.length} digits, ")
println(s"${md.substring(0, 20)}...${md.substring(md.length - 20)}")
println(s"fraction(s) with this denominator : ${maxDenFracs.toList}")
}
}
}</syntaxhighlight>
{{out}}
<pre>43/48 -> 1/2 + 1/3 + 1/16
5/121 -> 1/25 + 1/757 + 1/763309 + 1/873960180913 + 1/1527612795642093418846225
2014/59 -> [34] + 1/8 + 1/95 + 1/14947 + 1/670223480
 
For proper fractions with 1 or 2 digits:
largest number of items = 8
fraction(s) with this number : List(8/97, 44/53)
largest denominator = 150 digits, 57950458706754280171...62011424993909789665
fraction(s) with this denominator : List(8/97)
 
For proper fractions with 1, 2 or 3 digits:
largest number of items = 13
fraction(s) with this number : List(529/914, 641/796)
largest denominator = 2847 digits, 83901882683345018663...38431266995525592705
fraction(s) with this denominator : List(36/457, 529/914)</pre>
 
=={{header|Sidef}}==
{{trans|Ruby}}
<langsyntaxhighlight lang="ruby">func ef(fr) {
var ans = []
if (fr >= 1) {
Line 1,814 ⟶ 3,503:
"Term max is %s with %i terms\n".printf(lenmax[1].as_rat, lenmax[0])
"Denominator max is %s with %i digits\n".printf(denommax[1].as_rat, denommax[0].size)
say denommax[0]</langsyntaxhighlight>
{{out}}
<pre>
Line 1,826 ⟶ 3,515:
 
=={{header|Tcl}}==
<langsyntaxhighlight lang="tcl"># Just compute the denominator terms, as the numerators are always 1
proc egyptian {num denom} {
set result {}
Line 1,837 ⟶ 3,526:
}
return $result
}</langsyntaxhighlight>
Demonstrating:
{{works with|Tcl|8.6}}
<langsyntaxhighlight lang="tcl">package require Tcl 8.6
 
proc efrac {fraction} {
Line 1,874 ⟶ 3,563:
}
puts "$maxtf has maximum number of terms = [efrac $maxtf]"
puts "$maxdf has maximum denominator = [efrac $maxdf]"</langsyntaxhighlight>
{{out}}
<pre>
Line 1,885 ⟶ 3,574:
Note also that <math>\tfrac{44}{53}</math> also has 8 terms.
:<math>\tfrac{1}{2} + \tfrac{1}{4} + \tfrac{1}{13} + \tfrac{1}{307} + \tfrac{1}{120871} + \tfrac{1}{20453597227} + \tfrac{1}{697249399186783218655} + \tfrac{1}{1458470173998990524806872692984177836808420}</math>
 
=={{header|Visual Basic .NET}}==
{{trans|D}}
<syntaxhighlight lang="vbnet">Imports System.Numerics
Imports System.Text
 
Module Module1
 
Function Gcd(a As BigInteger, b As BigInteger) As BigInteger
If b = 0 Then
If a < 0 Then
Return -a
Else
Return a
End If
Else
Return Gcd(b, a Mod b)
End If
End Function
 
Function Lcm(a As BigInteger, b As BigInteger) As BigInteger
Return a / Gcd(a, b) * b
End Function
 
Public Class Rational
Dim num As BigInteger
Dim den As BigInteger
 
Public Sub New(n As BigInteger, d As BigInteger)
Dim c = Gcd(n, d)
num = n / c
den = d / c
If den < 0 Then
num = -num
den = -den
End If
End Sub
 
Public Sub New(n As BigInteger)
num = n
den = 1
End Sub
 
Public Function Numerator() As BigInteger
Return num
End Function
 
Public Function Denominator() As BigInteger
Return den
End Function
 
Public Overrides Function ToString() As String
If den = 1 Then
Return num.ToString()
Else
Return String.Format("{0}/{1}", num, den)
End If
End Function
 
'Arithmetic operators
Public Shared Operator +(lhs As Rational, rhs As Rational) As Rational
Return New Rational(lhs.num * rhs.den + rhs.num * lhs.den, lhs.den * rhs.den)
End Operator
 
Public Shared Operator -(lhs As Rational, rhs As Rational) As Rational
Return New Rational(lhs.num * rhs.den - rhs.num * lhs.den, lhs.den * rhs.den)
End Operator
 
'Comparison operators
 
Public Shared Operator =(lhs As Rational, rhs As Rational) As Boolean
Return lhs.num = rhs.num AndAlso lhs.den = rhs.den
End Operator
 
Public Shared Operator <>(lhs As Rational, rhs As Rational) As Boolean
Return lhs.num <> rhs.num OrElse lhs.den <> rhs.den
End Operator
 
Public Shared Operator <(lhs As Rational, rhs As Rational) As Boolean
'a/b < c/d
'ad < bc
Dim ad = lhs.num * rhs.den
Dim bc = lhs.den * rhs.num
Return ad < bc
End Operator
 
Public Shared Operator >(lhs As Rational, rhs As Rational) As Boolean
'a/b > c/d
'ad > bc
Dim ad = lhs.num * rhs.den
Dim bc = lhs.den * rhs.num
Return ad > bc
End Operator
 
Public Shared Operator <=(lhs As Rational, rhs As Rational) As Boolean
Return lhs < rhs OrElse lhs = rhs
End Operator
 
Public Shared Operator >=(lhs As Rational, rhs As Rational) As Boolean
Return lhs > rhs OrElse lhs = rhs
End Operator
 
'Conversion operators
Public Shared Widening Operator CType(ByVal bi As BigInteger) As Rational
Return New Rational(bi)
End Operator
Public Shared Widening Operator CType(ByVal lo As Long) As Rational
Return New Rational(lo)
End Operator
End Class
 
Function Egyptian(r As Rational) As List(Of Rational)
Dim result As New List(Of Rational)
 
If r >= 1 Then
If r.Denominator() = 1 Then
result.Add(r)
result.Add(New Rational(0))
Return result
End If
result.Add(New Rational(r.Numerator / r.Denominator))
r -= result(0)
End If
 
Dim modFunc = Function(m As BigInteger, n As BigInteger)
Return ((m Mod n) + n) Mod n
End Function
 
While r.Numerator() <> 1
Dim q = (r.Denominator() + r.Numerator() - 1) / r.Numerator()
result.Add(New Rational(1, q))
r = New Rational(modFunc(-r.Denominator(), r.Numerator()), r.Denominator * q)
End While
 
result.Add(r)
Return result
End Function
 
Function FormatList(Of T)(col As List(Of T)) As String
Dim iter = col.GetEnumerator()
Dim sb As New StringBuilder
 
sb.Append("[")
If iter.MoveNext() Then
sb.Append(iter.Current)
End If
While iter.MoveNext()
sb.Append(", ")
sb.Append(iter.Current)
End While
sb.Append("]")
Return sb.ToString()
End Function
 
Sub Main()
Dim rs = {New Rational(43, 48), New Rational(5, 121), New Rational(2014, 59)}
For Each r In rs
Console.WriteLine("{0} => {1}", r, FormatList(Egyptian(r)))
Next
 
Dim lenMax As Tuple(Of ULong, Rational) = Tuple.Create(0UL, New Rational(0))
Dim denomMax As Tuple(Of BigInteger, Rational) = Tuple.Create(New BigInteger(0), New Rational(0))
 
Dim query = (From i In Enumerable.Range(1, 100)
From j In Enumerable.Range(1, 100)
Select New Rational(i, j)).Distinct().ToList()
For Each r In query
Dim e = Egyptian(r)
Dim eLen As ULong = e.Count
Dim eDenom = e.Last().Denominator()
If eLen > lenMax.Item1 Then
lenMax = Tuple.Create(eLen, r)
End If
If eDenom > denomMax.Item1 Then
denomMax = Tuple.Create(eDenom, r)
End If
Next
 
Console.WriteLine("Term max is {0} with {1} terms", lenMax.Item2, lenMax.Item1)
Dim dStr = denomMax.Item1.ToString()
Console.WriteLine("Denominator max is {0} with {1} digits {2}...{3}", denomMax.Item2, dStr.Length, dStr.Substring(0, 5), dStr.Substring(dStr.Length - 5, 5))
End Sub
 
End Module</syntaxhighlight>
{{out}}
<pre>43/48 => [1/2, 1/3, 1/16]
5/121 => [1/25, 1/757, 1/763309, 1/873960180913, 1/1527612795642093418846225]
2014/59 => [34, 1/8, 1/95, 1/14947, 1/670223480]
Term max is 97/53 with 9 terms
Denominator max is 8/97 with 150 digits 57950...89665</pre>
 
=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|Wren-big}}
We use the BigRat class in the above module to represent arbitrary size fractions.
<syntaxhighlight lang="wren">import "./big" for BigInt, BigRat
 
var toEgyptianHelper // recursive
toEgyptianHelper = Fn.new { |n, d, fracs|
if (n == BigInt.zero) return
var divRem = d.divMod(n)
var div = divRem[0]
if (divRem[1] > BigInt.zero) div = div.inc
fracs.add(BigRat.new(BigInt.one, div))
var n2 = (-d) % n
if (n2 < BigInt.zero) n2 = n2 + n
var d2 = d * div
var f = BigRat.new(n2, d2)
if (f.num == BigInt.one) {
fracs.add(f)
return
}
toEgyptianHelper.call(f.num, f.den, fracs)
}
 
var toEgyptian = Fn.new { |r|
if (r.num == BigInt.zero) return [r]
var fracs = []
if (r.num.abs >= r.den.abs) {
var div = BigRat.new(r.num/r.den, BigInt.one)
var rem = r - div
fracs.add(div)
toEgyptianHelper.call(rem.num, rem.den, fracs)
} else {
toEgyptianHelper.call(r.num, r.den, fracs)
}
return fracs
}
 
BigRat.showAsInt = true
var fracs = [BigRat.new(43, 48), BigRat.new(5, 121), BigRat.new(2014, 59)]
for (frac in fracs) {
var list = toEgyptian.call(frac)
System.print("%(frac) -> %(list.join(" + "))")
}
 
for (r in [98, 998]) {
if (r == 98) {
System.print("\nFor proper fractions with 1 or 2 digits:")
} else {
System.print("\nFor proper fractions with 1, 2 or 3 digits:")
}
var maxSize = 0
var maxSizeFracs = []
var maxDen = BigInt.zero
var maxDenFracs = []
var sieve = List.filled(r + 1, null) // to eliminate duplicates
for (i in 0..r) sieve[i] = List.filled(r + 2, false)
for (i in 1..r) {
for (j in (i + 1)..(r + 1)) {
if (!sieve[i][j]) {
var f = BigRat.new(i, j)
var list = toEgyptian.call(f)
var listSize = list.count
if (listSize > maxSize) {
maxSize = listSize
maxSizeFracs.clear()
maxSizeFracs.add(f)
} else if (listSize == maxSize) {
maxSizeFracs.add(f)
}
var listDen = list[-1].den
if (listDen > maxDen) {
maxDen = listDen
maxDenFracs.clear()
maxDenFracs.add(f)
} else if (listDen == maxDen) {
maxDenFracs.add(f)
}
if (i < r / 2) {
var k = 2
while (true) {
if (j * k > r + 1) break
sieve[i * k][j * k] = true
k = k + 1
}
}
}
}
}
System.print(" largest number of items = %(maxSize)")
System.print(" fraction(s) with this number : %(maxSizeFracs)")
var md = maxDen.toString
System.write(" largest denominator = %(md.count) digits, ")
System.print("%(md[0...20])...%(md[-20..-1])")
System.print(" fraction(s) with this denominator : %(maxDenFracs)")
}</syntaxhighlight>
 
{{out}}
<pre>
43/48 -> 1/2 + 1/3 + 1/16
5/121 -> 1/25 + 1/757 + 1/763309 + 1/873960180913 + 1/1527612795642093418846225
2014/59 -> 34 + 1/8 + 1/95 + 1/14947 + 1/670223480
 
For proper fractions with 1 or 2 digits:
largest number of items = 8
fraction(s) with this number : [8/97, 44/53]
largest denominator = 150 digits, 57950458706754280171...62011424993909789665
fraction(s) with this denominator : [8/97]
 
For proper fractions with 1, 2 or 3 digits:
largest number of items = 13
fraction(s) with this number : [529/914, 641/796]
largest denominator = 2847 digits, 83901882683345018663...38431266995525592705
fraction(s) with this denominator : [36/457, 529/914]
</pre>
 
=={{header|zkl}}==
{{trans|Tcl}}
<langsyntaxhighlight lang="zkl"># Just compute the denominator terms, as the numerators are always 1
fcn egyptian(num,denom){
result,t := List(),Void;
Line 1,908 ⟶ 3,903:
else String("1/",denom);
}).concat(" + ")
}</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">foreach n,d in (T(T(43,48), T(5,121), T(2014,59))){
println("%s/%s --> %s".fmt(n,d, egyptian(n,d):efrac(_)));
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,919 ⟶ 3,914:
</pre>
For the big denominators, use GMP (Gnu Multi Precision).
<langsyntaxhighlight lang="zkl">var [const] BN=Import("zklBigNum"); // libGMP
lenMax,denomMax := List(0,Void),List(0,Void);
foreach n,d in (Walker.cproduct([1..99],[1..99])){ // 9801 fractions
Line 1,930 ⟶ 3,925:
dStr:=denomMax[0].toString();
println("Denominator max is %s/%s with %d digits %s...%s"
.fmt(denomMax[1].xplode(), dStr.len(), dStr[0,5], dStr[-5,*]));</langsyntaxhighlight>
{{out}}
<pre>
1,462

edits