Open In App

Greedy Algorithm for Egyptian Fraction

Improve
Improve
Like Article
Like
Save
Share
Report

Every positive fraction can be represented as sum of unique unit fractions. A fraction is unit fraction if numerator is 1 and denominator is a positive integer, for example 1/3 is a unit fraction. Such a representation is called Egyptian Fraction as it was used by ancient Egyptians. 

Following are a few examples: 

Egyptian Fraction Representation of 2/3 is 1/2 + 1/6
Egyptian Fraction Representation of 6/14 is 1/3 + 1/11 + 1/231
Egyptian Fraction Representation of 12/13 is 1/2 + 1/3 + 1/12 + 1/156

We can generate Egyptian Fractions using Greedy Algorithm. For a given number of the form ‘nr/dr’ where dr > nr, first find the greatest possible unit fraction, then recur for the remaining part. For example, consider 6/14, we first find ceiling of 14/6, i.e., 3. So the first unit fraction becomes 1/3, then recur for (6/14 – 1/3) i.e., 4/42. 

Below is the implementation of the above idea.

C++




/* C++ program to print a fraction in Egyptian Form using Greedy Algorithm*/
/*Efficient Approach */
#include <bits/stdc++.h>
using namespace std;
void egyptianFraction(int n, int d)
{
  //When Both Numerator and denominator becomes zero then we simply return;
    if (d == 0 || n == 0)
        return;
    if (d % n == 0) {
        cout << "1/" << d / n;
        return;
    }
    if (n % d == 0) {
        cout << n / d;
        return;
    }
    if (n > d) {
        cout << n / d << " + ";
        egyptianFraction(n % d, d);
        return;
    }
    int x = d / n + 1;
    cout << "1/" << x << " + ";
    egyptianFraction(n * x - d, d * x);
}
int main()
{
    int numerator = 6, denominator = 14;
    cout << "Egyptian Fraction representation of "
         << numerator << "/" << denominator << " is"
         << endl;
    egyptianFraction(numerator, denominator);
    return 0;
}


Java




// Java program to print a fraction
// in Egyptian Form using Greedy
// Algorithm
 
class GFG {
 
    static void printEgyptian(int nr, int dr)
    {
        // If either numerator or
        // denominator is 0
        if (dr == 0 || nr == 0) {
            return;
        }
 
        // If numerator divides denominator,
        // then simple division makes
        // the fraction in 1/n form
        if (dr % nr == 0) {
            System.out.print("1/" + dr / nr);
            return;
        }
 
        // If denominator divides numerator,
        // then the given number is not fraction
        if (nr % dr == 0) {
            System.out.print(nr / dr);
            return;
        }
 
        // If numerator is more than denominator
        if (nr > dr) {
            System.out.print(nr / dr + " + ");
            printEgyptian(nr % dr, dr);
            return;
        }
 
        // We reach here dr > nr and dr%nr
        // is non-zero. Find ceiling of
        // dr/nr and print it as first
        // fraction
        int n = dr / nr + 1;
        System.out.print("1/" + n + " + ");
 
        // Recur for remaining part
        printEgyptian(nr * n - dr, dr * n);
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        int nr = 6, dr = 14;
 
        // Calling the function and printing  the
        // corresponding Egyptian Fraction Representation
        System.out.print(
            "Egyptian Fraction Representation of " + nr
            + "/" + dr + " is\n ");
        printEgyptian(nr, dr);
    }
}


Python3




# Python3 program to print a fraction
# in Egyptian Form using Greedy
# Algorithm
 
# import math package to use
# ceiling function
import math
 
# define a function egyptianFraction
# which receive parameter nr as
# numerator and dr as denominator
def egyptianFraction(nr, dr):
 
    print("The Egyptian Fraction " +
          "Representation of {0}/{1} is".
                format(nr, dr), end="\n")
 
    # empty list ef to store
    # denominator
    ef = []
 
    # while loop runs until
    # fraction becomes 0 i.e,
    # numerator becomes 0
    while nr != 0:
 
        # taking ceiling
        x = math.ceil(dr / nr)
 
        # storing value in ef list
        ef.append(x)
 
        # updating new nr and dr
        nr = x * nr - dr
        dr = dr * x
 
    # printing the values
    for i in range(len(ef)):
        if i != len(ef) - 1:
            print(" 1/{0} +" .
                    format(ef[i]), end = " ")
        else:
            print(" 1/{0}" .
                    format(ef[i]), end = " ")
 
# calling the function
egyptianFraction(6, 14)
 
# This code is contributed
# by Anubhav Raj Singh


C#




// C# program to print a fraction
// in Egyptian Form using Greedy
// Algorithm
using System;
 
class GFG
{
static void printEgyptian(int nr, int dr)
{
    // If either numerator or
    // denominator is 0
    if (dr == 0 || nr == 0)
        return;
 
    // If numerator divides denominator,
    // then simple division  makes
    // the fraction in 1/n form
    if (dr % nr == 0)
    {
        Console.Write("1/" + dr / nr);
        return;
    }
 
    // If denominator divides numerator,
    // then the given number is not fraction
    if (nr % dr == 0)
    {
        Console.Write(nr / dr);
        return;
    }
 
    // If numerator is more than denominator
    if (nr > dr)
    {
        Console.Write(nr / dr + " + ");
        printEgyptian(nr % dr, dr);
        return;
    }
 
    // We reach here dr > nr and dr%nr
    // is non-zero. Find ceiling of
    // dr/nr and print it as first
    // fraction
    int n = dr / nr + 1;
    Console.Write("1/" + n + " + ");
 
    // Recur for remaining part
    printEgyptian(nr * n - dr, dr * n);
}
 
// Driver Code
public static void Main()
{
    int nr = 6, dr = 14;
    Console.Write( "Egyptian Fraction Representation of " +
                                 nr + "/" + dr + " is\n ");
    printEgyptian(nr, dr);
}
}
 
// This code is contributed
// by Akanksha Rai(Abby_akku)


Javascript




<script>
    // Javascript program to print a fraction
    // in Egyptian Form using Greedy
    // Algorithm
     
    function printEgyptian(nr, dr)
    {
        // If either numerator or
        // denominator is 0
        if (dr == 0 || nr == 0)
            return;
 
        // If numerator divides denominator,
        // then simple division  makes
        // the fraction in 1/n form
        if (dr % nr == 0)
        {
            document.write("1/" + parseInt(dr / nr, 10));
            return;
        }
 
        // If denominator divides numerator,
        // then the given number is not fraction
        if (nr % dr == 0)
        {
            document.write(parseInt(nr / dr, 10));
            return;
        }
 
        // If numerator is more than denominator
        if (nr > dr)
        {
            document.write(parseInt(nr / dr, 10) + " + ");
            printEgyptian(nr % dr, dr);
            return;
        }
 
        // We reach here dr > nr and dr%nr
        // is non-zero. Find ceiling of
        // dr/nr and print it as first
        // fraction
        let n = parseInt(dr / nr, 10) + 1;
        document.write("1/" + n + " + ");
 
        // Recur for remaining part
        printEgyptian(nr * n - dr, dr * n);
    }
     
      let nr = 6, dr = 14;
    document.write( "Egyptian Fraction Representation of " + nr + "/" + dr + " is\n ");
    printEgyptian(nr, dr);
 
// This code is contributed by divyeshrabadiya07.
</script>


PHP




<?php
// PHP program to print a fraction
// in Egyptian Form using Greedy
// Algorithm
 
function printEgyptian($nr, $dr)
{
    // If either numerator or
    // denominator is 0
    if ($dr == 0 || $nr == 0)
        return;
 
    // If numerator divides denominator,
    // then simple division makes the
    // fraction in 1/n form
    if ($dr % $nr == 0)
    {
        echo "1/", (int)$dr / $nr;
        return;
    }
 
    // If denominator divides numerator,
    // then the given number is not fraction
    if ($nr%$dr == 0)
    {
        echo (int)($nr / $dr);
        return;
    }
 
    // If numerator is more than denominator
    if ($nr > $dr)
    {
        echo (int)($nr/$dr), " + ";
        printEgyptian($nr % $dr, $dr);
        return;
    }
 
    // We reach here dr > nr and dr%nr is
    // non-zero. Find ceiling of dr/nr and
    // print it as first fraction
    $n = (int)($dr / $nr ) + 1;
    echo "1/" , $n , " + ";
 
    // Recur for remaining part
    printEgyptian($nr * $n - $dr, $dr * $n);
}
 
// Driver Code
$nr = 6;
$dr = 14;
echo "Egyptian Fraction Representation of ",
                    $nr, "/", $dr, " is\n ";
printEgyptian($nr, $dr);
     
// This code is contributed by ajit.
?>


Output

Egyptian Fraction representation of 6/14 is
1/3 + 1/11 + 1/231

Time complexity: The time complexity of the given algorithm depends on the value of the input fraction. In the worst case, the algorithm will run for O(d) iterations, where d is the denominator of the input fraction. Therefore, the time complexity of the algorithm is O(d).
Auxiliary Space:The space complexity of the given algorithm is O(1) as it uses only a fixed amount of extra space to store the variables used in the algorithm, regardless of the input size.

The recursive solution in Python is as follows:

C++




#include <bits/stdc++.h>
using namespace std;
vector<int> getEgyptianFractionUtil(int numerator, int denominator,
                        vector<int> listOfDenoms)
{
    if (numerator == 0)
        return listOfDenoms;
   
    int newDenom = ceil((double)denominator / numerator);
   
    // append in output list
    listOfDenoms.push_back(newDenom);
   
    listOfDenoms = getEgyptianFractionUtil(
        numerator * newDenom - denominator,
        newDenom * denominator, listOfDenoms);
   
    return listOfDenoms;
}
string getEgyptianFraction(int numerator, int denominator)
{
    string str = "";
    vector<int> output = getEgyptianFractionUtil(numerator, denominator, {});
    for (auto denom : output)
        str += "1/" + to_string(denom) + " + ";
   
    string strCopy = str.substr(0, str.length() - 3); // removing the last + sign
    return strCopy;
}
 
int main()
{
    cout << getEgyptianFraction(6, 14);
    return 0;
}
// This code is contributed by Abhijeet Kumar(abhijeet19403)


Java




import java.util.*;
 
public class Main {
 
    static Vector<Integer>
    getEgyptianFractionUtil(int numerator, int denominator,
                            Vector<Integer> listOfDenoms)
    {
        if (numerator == 0)
            return listOfDenoms;
 
        int newDenom = (int)Math.ceil((double)denominator
                                      / numerator);
 
        // append in output list
        listOfDenoms.add(newDenom);
 
        listOfDenoms = getEgyptianFractionUtil(
            numerator * newDenom - denominator,
            newDenom * denominator, listOfDenoms);
 
        return listOfDenoms;
    }
 
    static String getEgyptianFraction(int numerator,
                                      int denominator)
    {
        String str = "";
        Vector<Integer> output = getEgyptianFractionUtil(
            numerator, denominator, new Vector<Integer>());
        for (int denom : output)
            str += "1/" + Integer.toString(denom) + " + ";
 
        String strCopy = str.substring(
            0,
            str.length() - 3); // removing the last + sign
        return strCopy;
    }
 
    public static void main(String[] args)
    {
        System.out.println(getEgyptianFraction(6, 14));
    }
}


Python3




import math
 
 
def getEgyptianFraction(numerator, denominator):
    str = ""
    output = getEgyptianFractionUtil(numerator, denominator, [])
    for denom in output:
        str += "1/{0} + ".format(denom)
    strCopy = str[:-3# removing the last + sign
    return strCopy
 
 
def getEgyptianFractionUtil(numerator, denominator, listOfDenoms):
    if numerator == 0:
        return listOfDenoms
    newDenom = math.ceil(denominator/numerator)
    # append in output list
    listOfDenoms.append(newDenom)
    listOfDenoms = getEgyptianFractionUtil(numerator*newDenom - denominator,
                                           newDenom*denominator, listOfDenoms)
    return listOfDenoms
 
 
print(getEgyptianFraction(6, 14))
# Code contributed by
# Mayur Sonowal


Javascript




function getEgyptianFractionUtil(numerator, denominator, listOfDenoms) {
    if (numerator == 0) {
        return listOfDenoms;
    }
    let newDenom = Math.ceil((denominator / numerator));
 
    listOfDenoms.push(newDenom);
 
    listOfDenoms = getEgyptianFractionUtil(numerator * newDenom - denominator, newDenom * denominator, listOfDenoms);
 
    return listOfDenoms;
}
 
function getEgyptianFraction(numerator, denominator) {
    let str = "";
    let output = getEgyptianFractionUtil(numerator, denominator, []);
    for (let denom of output) {
        str += "1/" + denom + " + ";
    }
 
    let strCopy = str.substring(0, str.length - 3); // removing the last + sign
    return strCopy;
}
 
console.log(getEgyptianFraction(6, 14));
 
// This code is contributed by ishankhandelwals.


C#




using System;
using System.Collections.Generic;
using System.Linq;
 
namespace GFG {
class Program {
    static IEnumerable<int>
    getEgyptianFractionUtil(int numerator, int denominator,
                            IEnumerable<int> listOfDenoms)
    {
        if (numerator == 0)
            return listOfDenoms;
 
        int newDenom = (int)Math.Ceiling((double)denominator
                                         / numerator);
 
        // append in output list
        listOfDenoms
            = listOfDenoms.Concat(new int[] { newDenom });
 
        listOfDenoms = getEgyptianFractionUtil(
            numerator * newDenom - denominator,
            newDenom * denominator, listOfDenoms);
 
        return listOfDenoms;
    }
    static string getEgyptianFraction(int numerator,
                                      int denominator)
    {
        string str = "";
        IEnumerable<int> output = getEgyptianFractionUtil(
            numerator, denominator, new int[] {});
        foreach(int denom in output) str
            += "1/" + denom.ToString() + " + ";
 
        string strCopy = str.Substring(
            0, str.Length - 3); // removing the last + sign
        return strCopy;
    }
 
    static void Main(string[] args)
    {
        Console.WriteLine(getEgyptianFraction(6, 14));
    }
}
}


Output

1/3 + 1/11 + 1/231

Time complexity  The time complexity of the given code is O(N^2), where N is the maximum number of denominators in the Egyptian fraction representation of the given fraction. This is because the algorithm recursively calculates each denominator in the fraction representation, and each recursive call takes O(N) time.

Space complexity :The space complexity of the given code is O(N), where N is the maximum number of denominators in the Egyptian fraction representation of the given fraction. This is because the algorithm uses a vector to store the denominators, which can have at most N elements.

The Greedy algorithm works because a fraction is always reduced to a form where denominator is greater than numerator and numerator doesn’t divide denominator. For such reduced forms, the highlighted recursive call is made for reduced numerator. So the recursive calls keep on reducing the numerator till it reaches 1. 

 



Last Updated : 07 Apr, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads