Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sum up all the integers in range()

I need to write a program that sums up all the integers which can be divided by 3 in the range of 100 to 2000. I'm not even sure where to start, so far I've got this tiny piece of code written which isn't correct.

for x in range(100, 2001, 3):
      print(x+x)

Any help is much appreciated!

like image 521
mllnd Avatar asked Dec 08 '13 16:12

mllnd


3 Answers

Since you know the first number in this range that is divisible by 3 is 102, you can do the following:

Solution:

>>> sum(range(102, 2001, 3))
664650

To make it into a robust function:

def sum_range_divisible(start, end, divisor):
    while start % divisor != 0:
        start += 1
    return sum(range(start, end, divisor))

Using it:

>>> sum_range_divisible(100, 2001, 3)
664650

Note:

The advantage here is that you do not have to check each number in the whole range, since you are jumping by 3 each time.


Timing:

I have timed the different solutions, mine and aga's:

>>> import timeit
>>> timeit.Timer('sum(range(102, 2001, 3))').repeat()
[9.516391893850312, 9.49330620765817, 9.508695564438462]
>>> timeit.Timer('sum(x for x in range(100, 2001) if x % 3 == 0)').repeat()
[134.757627812011, 134.46399066622394, 138.34528734198346]

Conclusion:

My answer is faster by a factor of 14

like image 78
Inbar Rose Avatar answered Sep 19 '22 06:09

Inbar Rose


Use generator expression and sum function here:

res = sum(x for x in range(100, 2001) if x % 3 == 0)

It's pretty self-explanatory code: you're summing all the numbers from 100 to 2000, inclusive, which are divisible by three.

like image 21
aga Avatar answered Sep 19 '22 06:09

aga


There is a closed formula for that.

If (u_i) is a sequence defined by its first term u_0 and its common difference r, then the sum of the n first terms of (u_i) is:

\frac{n(u_0 + u_{n-1})}{2}

EDIT: I have made this little video to explain it visually.

A popular anecdote attributes this formula to the young Johann Carl Friedrich Gauss.

In your case:

  • u_0 = 102
  • u_{n-1} = 1998
  • n = (1998 - 102) / 3 + 1 = 633

So, the sum is (633 * (102 + 1998)) / 2 = 664650.

As a general Python function with the usual range arguments start, stop, step:

def arithmetic_series(start, stop, step):
    number_of_terms = (stop - start) // step
    sum_of_extrema = start + (stop - step)
    return number_of_terms * sum_of_extrema // 2

In your case, the call would be:

arithmetic_series(102, 2001, 3)

The complexity is O(1) instead of O(n), so unsurprisingly:

%timeit sum(range(102, 2001, 3))
100000 loops, best of 3: 17.7 µs per loop

%timeit arithmetic_series(102, 2001, 3)
1000000 loops, best of 3: 548 ns per loop
like image 41
Aristide Avatar answered Sep 18 '22 06:09

Aristide