Search code examples
algorithmrecursioncountgreatest-common-divisor

How to place the count variable in this gcd program based on Euclid's algorithm?


First of all, this is the Euclid's algorithm for calculating GCD (those who know it can skip straight away to the code).

GCD(m,n)=GCD(n,m mod n) and you keep performing this function until you get something like this: GCD(m,n)=GCD(answer,0). When you get this, you stop, that's what my program is trying to do. However I want to find another thing as well. The number of recursive GCD calls/divisions(let's call this variable as COUNT for conversation purposes) it takes for it to actually ARRIVE at the answer. For example

GCD(60,24) = GCD (24, 12) = GCD (12, 0) =12 so the COUNT here would be 3(including the last one) since we used Euclid's algorithm twice.

P.S in the code below, I am trying to print COUNT along with GCD values for a combination of numbers and I seem to get wrong answers.

P.P.S I hope I have explained this properly.

Here is the code

#include<stdio.h>
int gcd(int m , int n);
int count=0;
int main()
{
    int m,n;
    for(m=1;m<=10;m++)
    {
        for(n=1;n<=m;n++)
        {
            printf("gcd of %d, %d is :%d",m,n,gcd(m,n));
            printf(" with %d iterations\n",count);
        }
    }
}

int gcd(int m , int n)
{
    if(n==0)
    {
        return m;
        count=0;
    }
    if(m<n)
    {
        //swapping both a and b
        m=m+n;
        n=m-n;
        m=m-n;
    }
    else
    {
        count++;
        return gcd(n, m%n); 
    }
}

Solution

  • First of all, your count = 0 is after the return statement. Thus, it's never executed!

    However, even after you switch count = 0 and return, it's still incorrect because you basically set count to 0 after you increase count. For example:

    gcd(60,24) => count++ => count = 1
    gcd(24, 12) => count++ => count = 2
    gcd(12, 0) => count = 0 => count = 0
    

    The right way is to do the following:

    count = 0
    gcd(60,24) => count++ => count = 1
    gcd(24, 12) => count++ => count = 2
    gcd(12, 0) => count++ => count = 3
    

    Also, the flow of your code is incorrect. What will happen if you call gcd(5, 15)? You swap 5 and 15, but then you didn't return anything at all! The way to fix it is to remove the else statement.

    Here's the refactored code:

    #include<stdio.h>
    
    int gcd(int m , int n);
    int gcd_wrapper(int m, int n);
    
    int count=0;
    
    int main(){
        int m,n;
        for(m=1;m<=10;m++)
        {
            for(n=1;n<=m;n++)
            {
                printf("gcd of %d, %d is :%d",m,n,gcd_wrapper(m,n));
                printf(" with %d iterations\n",count);
            }
        }
        return 0;
    }
    
    int gcd_wrapper(int m, int n) {
        count = 0;
        return gcd(m, n);
    }
    
    int gcd(int m , int n){
        count++;
        if(n == 0){
            return m;
        }
        if(m < n){
            //swapping both a and b
            m=m+n;
            n=m-n;
            m=m-n;
        }
        return gcd(n, m%n); 
    }