views:

298

answers:

8

ok so I am feeling a little stupid for not knowing this, but a coworker asked so I am asking here: I have written a python algorithm that solves his problem. given x > 0 add all numbers together from 1 to x.

def intsum(x):
  if x > 0:
    return x + intsum(x - 1)
  else:
    return 0

intsum(10)
55

first what is this type of equation is this and what is the correct way to get this answer as it is clearly easier using some other method?

+14  A: 

This is recursion, though for some reason you're labeling it like it's factorial.

In any case, the sum from 1 to n is also simply:

n * ( n + 1 ) / 2

(You can special case it for negative values if you like.)

Larry
Thanks, I just used the closest math term I could grab for a def name, changed it to reflect. arithmetic sequence is the name then. Appreciated.
Gabriel
How Gauß discovered this when he was 9 is one of my favorite anecdotes :-)
THC4k
Every J. Random Hacker's chainsaw implementation of an asciify or de-accenter changes the name from Gauß to Gau :-(
John Machin
@THC4k you should provide a link to the story, I would love to read it.
Gabriel
http://betterexplained.com/articles/techniques-for-adding-the-numbers-1-to-100/
starblue
@Gabriel, starblue's article has a link at the end http://www.americanscientist.org/issues/pub/2006/3/gausss-day-of-reckoning
Unreason
+1  A: 

Consider that N+1, N-1+2, N-2+3, and so on all add up to the same number, and there are approximately N/2 instances like that (exactly N/2 if N is even).

Jerry Coffin
Maths hurts my brain, and I don't like it.
Andy Hume
+1  A: 

What you have there is called arithmetic sequence and as suggested, you can compute it directly without overhead which might result from the recursion.

And I would say this is a homework despite what you say.

Gabriel Ščerbák
lol, no my wife would be laughing at me right now if she found out I didn't know this (i help her with her math homework). This is really for my coworker. And thanks for the name.
Gabriel
np, seems too easy, but happens to me as well:)
Gabriel Ščerbák
+4  A: 

Here is how to prove the closed form for an arithmetic progression

S  = 1 +   2   + ... + (n-1) + n
S  = n + (n-1) + ... +   2   + 1
2S = (n+1) + (n+1) + ... + (n+1) + (n+1)
     ^ you'll note that there are n terms there.
2S = n(n+1)
S = n(n+1)/2
Rob Rolnick
+3  A: 

Larry is very correct with his formula, and its the fastest way to calculate the sum of all integers up to n.

But for completeness, there are built-in Python functions, that perform what you have done, on lists with arbitrary elements. E.g.

  • sum()

    >>> sum(range(11))
    55
    >>> sum([2,4,6])
    12
    
  • or more general, reduce()

    >>> import operator
    >>> reduce(operator.add, range(11))
    55
    
Felix Kling
interesting that sum actually gave me an invalid result. I tried the syntax you entered and go 45, not 55.
Gabriel
that's because range(10) is from 0 to 9.
Dingle
@Gabriel: Ups, my bad. Of course it should be `range(11)`... It was too late when I wrote this...
Felix Kling
+8  A: 

Transforming recursively-defined sequences of integers into ones that can be expressed in a closed form is a fascinating part of discrete mathematics -- I heartily recommend Concrete Mathematics: A Foundation for Computer Science, by Ronald Graham, Donald Knuth, and Oren Patashnik (see. e.g. the wikipedia entry about it).

However, the specific sequence you show, fac(x) = fac(x - 1) + x, according to a famous anecdote, was solved by Gauss when he was a child in first grade -- the teacher had given the pupils the taksk of summing numbers from 1 to 100 to keep them quet for a while, but two minutes later there was young Gauss with the answer, 5050, and the explanation: "I noticed that I can sum the first, 1, and the last, 100, that's 101; and the second, 2, and the next-to-last, 99, and that's again 101; and clearly that repeats 50 times, so, 50 times 101, 5050". Not rigorous as proofs go, but quite correct and appropriate for a 6-years-old;-).

In the same way (plus really elementary algebra) you can see that the general case is, as many have already said, (N * (N+1)) / 2 (the product is always even, since one of the numbers must be odd and one even; so the division by two will always produce an integer, as desired, with no remainder).

Alex Martelli
+1 for the Gauss anecdote, reminded me of my father :)
Agos
It's a rigorous proof, it's just not couched in the mess of symbols that we usually associate with "rigor" (which makes it a better proof, in my estimation).
Stephen Canon
@Stephen, it's not rigorous because of the "clearly" hand-waving -- it could easily be made so (without symbols, that would just make it longer;-).
Alex Martelli
It's "clear" enough that I would consider it rigorous in any context other than a first semester course in proofs.
Stephen Canon
Probably concrete mathematics for most programmers is toooo difficult. And the summation problem I think is very easy, usually understand for junior school student.
xiao
@Turtle, I disagree that Graham-Knuth-Patashnik's book is too difficult for most programmers -- I'm an optimist, I believe in people and their brain's potential, they just need to be stimulated and challenged to use and develop it! And, sure, I did mention how the specific problem of summation was in fact first solved by a first grader (though not exactly an average or ordinary one;-).
Alex Martelli
Small typo there: it's n * (n+1) / 2.
Pin
@Pin, right, tx, let me edit.
Alex Martelli
+3  A: 

I'm not allowed to comment yet so I'll just add that you'll want to be careful in using range() as it's 0 base. You'll need to use range(n+1) to get the desired effect.

Sorry for the duplication...

sum(range(10)) != 55

sum(range(11)) == 55

edstafford
I noticed that as well when I tested the proof on my python. +1, hope you get comment soon.
Gabriel
+3  A: 

OP has asked, in a comment, for a link to the story about Gauss as a schoolchild.

He may want to check out this fascinating article by Brian Hayes. It not only rather convincingly suggests that the Gauss story may be a modern fabrication, but outlines how it would be rather difficult not to see the patterns involved in summing the numbers from 1 to 100. That in fact the only way to miss these patterns would be to solve the problem by writing a program.

The article also talks about different ways to sum arithmetic progressions, which is at the heart of OP's question. There is also an ad-free version here.

brainjam