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?
The formula for the sum of the first n positive integers is n(n+1)/2. This formula works for consecutive integers. Thanks!
Therefore, the sum of all positive integers up to 1000, which are divisible by 5 and not divisible by 2 is 50000.
So, the sum of all the natural numbers between 1 and 100 that are divisible by 2 is 2550.
Thus, the sum of the integers from 1 to 100, which are divisible by 2 or 5, is 3050.
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.
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;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With