Program to find lcm of first n numbers

I came across this problem in Project euler. http://projecteuler.net/problem=5

Find the smallest number which is divisible by all numbers from 1 to 20. 2520 is the smallest number which is divisible by all numbers from 1 to 10.

Now to find lcm of two numbers, we have a formula

lcm = product of a, b/ gcd of a,b

But lcm of more than two numbers? How do we calculate it?

lcm of a,b,c = lcm of ( lcm of a,b ) and c
lcm of a,b,c,d = lcm of (lcm of a,b,c) and d ... and so on.

To find gcd (greatest common divisor ) we have Euclid's algorithm

gcd(a,b) = b
                    if a is divisible by b  i.e. a%b is 0
                gcd (b, a%b)
                    if a is not divisible by b

So now we are almost ready to write our set of functions.

int gcd(int a,int b)
{
   if ( a% b==0)
       return b;
    return gcd(b, a% b);
}

int lcm(int a,int b)
{
    int product,hcf,divisor;
   
    hcf = gcd(a,b);
    if (hcf==b)
    {
divisor = a;
    }
    else
    {
 divisor = (a*b)/hcf;
    }
    return divisor;
}
int lcm_first_n_numbers(int n)
{
    int lc = 1; int i;
    for( i = 1;i<=n;i++)
    {
        lc = lcm(lc,i);
}
    return lc;
}

As we can see, first function calculates gcd of two numbers, second function finds out lcm and third function calculates lcm of first n numbers iterativerly.
We added if (hcf==b)...... statement to avoid unnecessary multiplication and division if b is already gcd of a and b.

Things would run smoothly from here but for a problem. For larger numbers, lcm exceeds the integer range, we should use float instead. And % operator does not work on floats. So we should type cast the values to int.

Here are our functions with these changes
float gcd(float a,float b)
{
   if (( int)a%( int)b==0)
       return b;
    return gcd(b,( int)a%( int)b);
}

float lcm(float a,float b)
{
    float product,hcf,divisor;
   
    hcf = gcd(a,b);
if (hcf==b)
{
divisor = a;
}
else
{
 divisor = (a*b)/hcf;
 }
return divisor;
}

float lcm_first_n_numbers(float n)
{
    float lc = 1; int i;
    for( i = 1;i<=n;i++)
    {
        lc = lcm(lc,i);
}
return lc;
}
int main()
{
         int  n; float least_common_divisor;
printf("Enter n:");
scanf("%d",&n);
least_common_divisor = lcm_first_n_numbers(n);
printf("The smallest divisor of all numbers from 1 to %d is %f\n",n,least_common_divisor);
}


In fact I got wrong answer for n = 20, then I added the step of multiplying a and b only if gcd is not b. This gave me the correct answer. Problem was with floating point arithmetic.

 

Comments

  1. Great and Simple Programs. Would also recommend your readers to have a look at C Program To Find LCM of N Numbers using Functions and Arrays. It is described in two different scenarious.

    ReplyDelete

Post a Comment

Popular Posts