Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find the sum of all numbers between 1 and N divisible by either x or y

Say we have 3 numbers N, x and y which are always >=1.

N will be greater than x and y and x will be greater than y.

Now we need to find the sum of all number between 1 and N that are divisible by either x or y.

I came up with this:

sum = 0;
for(i=1;i<=N;i++)
{
  if(i%x || i%y)
    sum += i;
}

Is there a way better way of finding the sum avoiding the for loop?

I've been pounding my head for many days now but have not got anything better.

If the value of N has a upper limit we can use a lookup method to speedup the process.

Thanks everyone.

I wanted a C/C++ based solution. Is there a built-in function to do this? Or do I have to code the algorithm?

like image 738
user545682 Avatar asked Dec 17 '10 05:12

user545682


People also ask

How do you find the sum of all numbers between 1 and n?

The formula for the sum of the first n positive integers is n(n+1)/2. This formula works for consecutive integers. Thanks!

What is the sum of all the numbers between 1 and 1000 which are divisible by 5 but not by 2?

Therefore, the sum of all positive integers up to 1000, which are divisible by 5 and not divisible by 2 is 50000.

What is the sum of all numbers between 1 and 100 which are divisible by 2?

So, the sum of all the natural numbers between 1 and 100 that are divisible by 2 is 2550.

What is the sum of numbers from 1 to 100 which are divisible by 2 or 5?

Thus, the sum of the integers from 1 to 100, which are divisible by 2 or 5, is 3050.


2 Answers

Yes. You can void the for loop altogether and find the sum in constant time.

According to the Inclusion–exclusion principle summing up the multiples of x and multiples of y and subtracting the common multiple(s) that got added twice should give us the required sum.

Required Sum = sum of ( multiples of x that are <= N ) +      
               sum of ( multiples of y that are <= N ) -
               sum of ( multiples of (x*y) that are <= N )

Example:

N = 15
x = 3
y = 4

Required sum = ( 3 + 6 + 9 + 12 + 15) +  // multiples of 3
               ( 4 + 8 + 12 ) -          // multiples of 4
               ( 12 )                    // multiples of 12

As seen above we had to subtract 12 as it got added twice because it is a common multiple.

How is the entire algorithm O(1)?

Let sum(x, N) be sum of multiples of x which are less than or equal to N.

sum(x,N) = x + 2x + ... + floor(N/x) * x
         = x * ( 1 + 2 + ... + floor(N/x) )
         = x * ( 1 + 2 + ... + k)    // Where k = floor(N/x)
         = x * k * (k+1) / 2         // Sum of first k natural num = k*(k+1)/2

Now k = floor(N/x) can be computed in constant time.

Once k is known sum(x,N) can be computed in constant time.

So the required sum can also be computed in constant time.

EDIT:

The above discussion holds true only when x and y are co-primes. If not we need to use LCM(x,y) in place of x*y. There are many ways to find LCM one of which is to divide product by GCD. Now GCD cannot be computed in constant time but its time complexity can be made significantly lesser than linear time.

like image 64
codaddict Avatar answered Oct 15 '22 14:10

codaddict


If a number is divisible by X, it has to be a multiple of x. If a number is divisible by Y, it has to be a multiple of y.

I believe, if you do a for loop for all multiples of x and y, and avoid any duplicates, you should get the same answer.

Out of my head, something of the type:

sum = 0
for( i=x; i<=n; i+=x)
    sum += i;

for( i=y; i<=n; i+=y)
    if( y % x != 0 )
        sum += i;   
like image 34
Nican Avatar answered Oct 15 '22 15:10

Nican