Problem : Define "recursion". What does it mean for a function to be recursive?

Recursion is an algorithmic technique where a function, in order to accomplish a task, calls itself with some part of the task. A recursive function calls itself on a simpler version of the problem in an attempt to simplify the problem to a point where it can be solved. With this smaller problem solved, it can work backwards to solve each slightly larger problem until the entire problem has been solved.

Problem : Your boss asks you to write a function to sum up all of the numbers between some high and low value. You decide to write two different versions of the function, one recursive and one iterative. 1) Write them. The next morning you come into work and your boss calls you into his office, unhappy at how slow both of your functions work, compared to how the problem could be solved. 2) How else could you solve this problem?

1a) Iteratively:
int sum_nums(int low, int high) { int i, total=0; for(i=low; i<=high; i++) total+=i; return total; }
1b) Recursively:
int sum_nums(int low, int high) { if (low == high) return high; else return low + sum_nums(low+1, high); }
2) Certain mathematical functions have closed form expressions; this means that there is actually a mathematical expression that can be used to explicitly evaluate the answer, thereby solving the problem in constant time, as opposed to the linear time it takes for the recursive and iterative versions.
int sum_nums(int low, int high) { return (((high*(high+1))/2) - (((low-1)*low)/2); }

Problem : What is a base case? Why must a recursive function have a base case? Can a function be written recursively if a base case is not known?

The base case(s), or halting case(s), are the conditions under which a recursive function stops recurring. The base case is the small problem we know how to solve. Every recursive function must have a base case in order to stop (the base case is the point at which the recursion halts); if a base case did not exist, the function would keep recurring until it exhausted the system's resources and most likely crashed your program. If a base case is not known, a function cannot be written recursively.

Problem : What is wrong with the following function?

int factorial(int n) { if (n<=1) return 1; else if (n<0) return 0; else return factorial(n-1) * n; }

The first two if statements should be switched. This function works fine if the function is called on valid input (n > = 0). But if it is called on invalid input (n < 0), the function will incorrectly return 1.

Problem : Your research assistant has come to you with the following two functions:

int factorial_iter(int n) { int fact=1; if (n<0) return 0; for( ; n>0; n--) fact *= n; return(fact); }
and
int factorial_recur(int n) { if (n<0) return 0; else if (n<=1) return 1; else return n * factorial_recur(n-1); }
He claims that the factorial_recur() function is more efficient because it has fewer local variables and thus uses less space. What do you tell him?

Every time the recursive function is called, it takes up stack space (we'll discuss this more exhaustively in the section) and space for its local variables are set aside. So actually, the recursive version takes up much more space overall than does the iterative version.

Problem : As you probably noticed, the size of n! grows quickly as n increases. As such, you will probably reach a point were your computer can no longer represent the value of n! (unless you are using language with a big number library or unlimited integer precision). Determine what the largest value of n is for which the computer can accurately compute n!.

This depends on your computer. Try running the factorial function with increasing values of n and see where something strange happens.

Problem : Back to the problem of programming Data to walk. Write a function void walk(int n) that takes n steps. You should use the void take_one_step() function as a helper function.

void walk(int n) { if (n>=1) take_one_step(); if (n>1) walk(n-1); }