views:

791

answers:

9

Okay so i need really FAST algorithm or code in C if you have any it would be nice. The task is to sum all numbers from 1 to N for a given number N (it can be negative number too), so i did the usual way (you know just summing with loop from 1 to N) but it's not fast enough - i need something faster, i guess that i need the fastest possible way to do this.

If anyone could help me, please do. Thanks.

+22  A: 
sum = N * (N + 1) / 2
florin
But that's only O(1)!
dancavallaro
indeed the fastest :)
ldog
@dancavallaro: not if you count bitwise operations its not!
ldog
you could always hard code the summation values of −32,768 to +32,767. Even fewer cycles :D
srand
I do not think it works with negative number. If N is -3, this formula give 3 but -3+-2+-1+0+1 = -5
Daok
@gmatt is correct, this is actually `O(log N)`, unless you limit the value of `N`, in which case the naïve loop is `O(1)` as well.
avakar
@avakar: I upvoted your comment, but do `O(log N)` multipliers really exist? Wikipedia doesn't list any: http://en.wikipedia.org/wiki/Computational_complexity_of_mathematical_operations
erikkallen
@erikkallen, my bad, I was thinking "at least `log N`", it should say `\Omega(log N)`.
avakar
If my understanding of wikipedia is correct, the Schönhage-Strassen algorithm (which appears to be the fastest discovered, practically usable algorithm) would geve a time complexity for this problem of `O(log N log log N log log log N)`
erikkallen
+24  A: 

If N is positive: int sum = N*(N+1)/2;

If N is negative: int tempN = -N; int sum = 1 + tempN*(tempN+1)/2 * (-1);.

IVlad
If `N` is zero, 1?
GMan
"If N is negative" needs a `+ 1` on the end. 1 + 0 + -1 + -2 = -2, not -3.
tloflin
Oops! Thanks, missed it.
IVlad
@Dave: Yes, you should always perform premature optimization because it really makes a difference, and the compiler would never be smart enough to figure that out by itself. Also note that it might be faster because it does not do the same thing (you'd want `>> 1`).
erikkallen
No explanation on *how* this works? I'll give it a shot: `N/2` finds the average value of all numbers between 0 and N. We're starting at 1, so change that to `(N+1)/2`. Now that we have the average value, we just need to multiply that by the number of values in the sequence (N) (actually N-1(starting value)+1(1 to 2 contains 2 values, not 2-1=1), but N-1+1=N). So `N*((N+1)/2)`, reduced = `N*(N+1)/2`.
Wallacoloo
@erikkallen: (upvote for my smile). Plus I believe the right shift is implementation-defined for signed data?
Dan
There's a good inductive proof of this, too, in case you need more than a simple demonstration.
avpx
A: 

Try this...

Where n is the maximum integer you need to sum to.

The sum is (n*(N+1))/2

adengle
A: 

To deal with integer overflow I'd use the following function:

sum = (N%2) ? ( ((N+1)/2)*N ) : ( (N/2)*(N+1) );
Kirill V. Lyadvinsky
clever... But this is *still* vulnerable to integer overflow. You aren't "dealing" with it, merely delaying it.
Wallacoloo
It will "delay" it as long as possible.
Kirill V. Lyadvinsky
A: 

int sum(int n) { return (n < 0 ? n *(-n + 1) / 2 + 1 : n * ( n + 1) / 2); }

upt1me
+13  A: 

The formula you're looking for is a more general form of the one posted in multiple answers to your question, which is an Arithmetic Series/Progression with a difference factor of 1. From Wikipedia, it is the following:

alt text

The above formula will handle negative numbers as long as m is always less than n. For example to get the sum from 1 to -2, set m to -2 and n to 1, i.e. the sum from -2 to 1. Doing so results in:

(1 - -2 + 1) * (1 + -2) / 2 = 4 * -1 / 2 = -4 / 2 = -2.

which is the expected result.

Void
+1 for giving the general formula.
Matthieu M.
+5  A: 

Just to complete the above answers, this is how you prove the formula (sample for positive integer but principle is the same for negatives or any arithmetic suite as Void pointed out).

Just write the suite two times as below and add numbers:

  1+   2+   3+ ... n-2+ n-1+   n   = sum(1..n)     : n terms from 1 to n
+ n+ n-1+ n-2+ ...   3+   2+   1   = sum(n..1)     : the same n terms in reverse order
--------------------------------
n+1+ n+1+ n+1+ ... n+1+ n+1+ n+1   = 2 * sum(1..n) : n times n+1

n * (n+1) / 2 = sum(1..n)
kriss
third term of sum(n..1) should be n-2.
Wallacoloo
+1 for explaining it intuitively
Anurag
+1 Nicely, done.
Void
@wallacoloo: thanks. I corrected the answer (and also another typo).
kriss
@Void: thanks but I've no merit, it's Gauss's classical proof.
kriss
You know compleat can only be used as an adjective and not a verb, right?
Ben Voigt
@Ben Voigt: Only if you don't know how to verb adjectives :D
Wallacoloo
A: 

have you heard about sequence & series ? The 'fast' code that you want is that of sum of arithmetic series from 1 to N .. google it .. infact open your mathematics book..

sp3tsnaz
A: 

if |n| is small enough, a lookup table will be the fastest one.

or using a cache, first search the cache, if can't find the record then caculate the sum by using n * (n + 1) / 2(if n is positive), and record the result into the cache.

wenlujon