stack call order Fibonacci clarification - recursion

I'm trying to clarify the order in which recursive calls get executed. I read through this link:
Dynamic programming and Divide and conquer
The function was written like this:
int Fibonacci(int n) {
if (n <= 1) return n;
return Fibonacci(n - 1) + Fibonacci(n - 2);
}
The call order was described like this:
If you trace out the calls done to compute Fibonacci(4), we get
Fibonacci(4) calls Fibonacci(3) and Fibonacci(2)
Fibonacci(3) calls Fibonacci(2) and Fibonacci(1)
Fibonacci(2) calls Fibonacci(1) and Fibonacci(0)
Fibonacci(2) (the other one) calls Fibonacci(1) and Fibonacci(0)
Fibonacci(1) terminates.
Fibonacci(1) terminates.
Fibonacci(1) terminates.
Fibonacci(0) terminates.
Fibonacci(0) terminates.
This brings up two questions:
(1) For this code:
return Fibonacci(n - 1) + Fibonacci(n - 2);
Does the call on the left-hand-side of the + sign always get called before the call on the right hand side? I think we get some sort of depth-first chain of function calls, where the straight line call Fib(5)...Fib(4)...Fib(3)...Fib(2)...Fib(1)
gets called in a row before anything else gets called in the tree branching process. Is that true?
(2) I'm not understanding why the branches terminate in this order:
Fibonacci(1) terminates.
Fibonacci(1) terminates.
Fibonacci(1) terminates.
Fibonacci(0) terminates.
Fibonacci(0) terminates.
I thought the termination order would simply be the leaf-order from left-to-right at the bottom of the tree:
1 0 1 1 0
Thanks for any insights on this.

I guess you are right. I just did a small test:
int fibo(int n) {
if (n <= 1) return n;
System.out.println("fibo " + n + " calls fibo " + (n - 1) + " and fibo " + (n - 2));
int f1 = fibo(n - 1);
System.out.println("fibo " + (n - 1) + " terminates");
int f2 = fibo(n - 2);
System.out.println("fibo " + (n - 2) + " terminates");
return f1 + f2;
}
And got:
fibo 4 calls fibo 3 and fibo 2
fibo 3 calls fibo 2 and fibo 1
fibo 2 calls fibo 1 and fibo 0
fibo 1 terminates
fibo 0 terminates
fibo 2 terminates
fibo 1 terminates
fibo 3 terminates
fibo 2 calls fibo 1 and fibo 0
fibo 1 terminates
fibo 0 terminates
fibo 2 terminates
As you can see, the termination sequence for the base cases is 1 0 1 1 0.

You didn't specify a language, so the order of invocation isn't guaranteed when you have two calls on a single line. Some languages or compilers specify what they'll do, others don't.
Assuming left-to-right evaluation, I broke things up into explicit calls with print statements to show explicitly where things happen. Since no language was specified I did this in Ruby:
def fib(n)
return n if n <= 1
puts "fib(#{n}) calls fib(#{n-1})"
f1 = fib(n-1)
puts "fib(#{n-1}) returns to fib(#{n})"
puts "fib(#{n}) calls fib(#{n-2})"
f2 = fib(n-2)
puts "fib(#{n-2}) returns to fib(#{n})"
f1 + f2
end
It produced the following output:
irb(main):011:0> fib(4)
fib(4) calls fib(3)
fib(3) calls fib(2)
fib(2) calls fib(1)
fib(1) returns to fib(2)
fib(2) calls fib(0)
fib(0) returns to fib(2)
fib(2) returns to fib(3)
fib(3) calls fib(1)
fib(1) returns to fib(3)
fib(3) returns to fib(4)
fib(4) calls fib(2)
fib(2) calls fib(1)
fib(1) returns to fib(2)
fib(2) calls fib(0)
fib(0) returns to fib(2)
fib(2) returns to fib(4)
=> 3
which I think makes pretty clear what's being done, and in what order.

Related

how do I count the amount of times a (recursive) function executes itself in ocaml?

needing some help (if possible) in how to count the amount of times a recursive function executes itself.
I don't know how to make some sort of counter in OCaml.
Thanks!
Let's consider a very simple recursive function (not Schroder as I don't want to do homework for you) to calculate Fibonacci numbers.
let rec fib n =
match n with
| 0 | 1 -> 1
| _ when n > 0 -> fib (n - 2) + fib (n - 1)
| _ -> raise (Invalid_argument "Negative values not supported")
Now, if we want to know how many times it's been passed in, we can have it take a call number and return a tuple with that call number updated.
To get each updated call count and pass it along, we explicitly call fib in let bindings. Each time c shadows its previous binding, as we don't need that information.
let rec fib n c =
match n with
| 0 | 1 -> (1, c + 1)
| _ when n > 0 ->
let n', c = fib (n - 1) (c + 1) in
let n'', c = fib (n - 2) (c + 1) in
(n' + n'', c)
| _ -> raise (Invalid_argument "Negative values not supported")
And we can shadow that to not have to explicitly pass 0 on the first call.
let fib n = fib n 0
Now:
utop # fib 5;;
- : int * int = (8, 22)
The same pattern can be applied to the Schroder function you're trying to write.
You can create a reference in any higher scope like so
let counter = ref 0 in
let rec f ... =
counter := !counter + 1;
... (* Function body *)
If the higher scope happens to be the module scope (or file top-level scope) you should omit the in
You can return a tuple (x,y) where y you increment by one for each recursive call. It can be useful if your doing for example a Schroder sequence ;)

Can a recursive method have more than one base case in Pascal?

I was wondering if you can have more than just one base case on a recursive procedure/function in Pascal.
If so, can you please give me a simple example? And please explain why this is possible?
The simple Fibonacci sequence has two base cases:
f(0) = 0
f(1) = 1
f(n) = f(n - 1) + f(n - 2)
And, of course, you can write it in Pascal:
function Fib(n: integer): integer;
begin
if n = 0 then Fib := 0
else if n = 1 then Fib := 1
else Fib := Fib(n - 1) + Fib(n - 2)
end;

complexity on recursive Big-O

I have a Computer Science Midterm tomorrow and I need help determining the complexity of these recursive functions. I know how to solve simple cases, but I am still trying to learn how to solve these harder cases. Any help would be much appreciated and would greatly help in my studies, Thank you!
fonction F(n)
if n == 0
return 1
else
return F(n-1) * n
fonction UniqueElements(A[0..n-1])
for i=0 to i <= n-2 do
for j=i+1 to j <= n-1 do
if A[i] == A[j]
return false
return true
fonction BinRec(n)
if n == 1
return 1
else
return BinRec(floor(n/2)) + 1
For hands on learning, you can plug the functions into a program, and test their worst case scenario performance.
When trying to calculate O by hand, here are some things to remember
The +, -, *, and / offsets can be ignored. So 1 to n+5 and 1 to 5n is considered equivalent to 1 to n.
Also, Only the highest order of magnitude counts, so for O 2^n + n^2 + n, 2^n grows the fastest, so it is equivalent to O 2^n
With recursive functions, you are looking at how many times the function is called in the method (the split count) and how much it needs to be called (the depth, usually is equal to list length). So the final O will be depth_count^split_count
With loops, each nested loop multiplies to the one it's in, and sequential loops add, so (1-n){(1-n){}} (1-n){} is (n * n) + n) => n^2 + n =(only highest growth counts)> n^2
PRACTICE! You will need to practice to get the hang of the gatchas of growth rate and how control flows interact. (so do online practice quizs)
function F(n){
count++
if (n == 0)
return 1
else
return F(n-1) * n
}
function UniqueElements(A){
for (var i=0 ; i <= A.length-2; i++){
for (var j=i+1;j <= A.length-1; j++){
if (A[i] == A[j]){
return false
}
}
}
return true
}
function BinRec(n) {
count++
if (n == 1)
return 1
else
return BinRec(Math.floor(n/2)) + 1
}
count = 0;
console.log(F(10));
console.log(count);
count = 0;
console.log(UniqueElements([1,2,3,5]));
console.log(count);
count = 0;
console.log(BinRec(40));
console.log(count);

SML: Keeping track of number of iterations

I'm sure there's a way to do this elegantly in SML but I'm having difficulty keeping track of the number of iterations (basically the number of times my function has been called).
I'm trying to write a function that evaluates to a pair of numbers, one for the floor of the answer and the other for the remainder. So if you called:
divmod(11, 2), you'd get (5, 1) back.
Here's what I have so far:
divmod(number : int, divisor : int) =
if number < divisor then
(number, count)
else
divmod(number - divisor, divisor);
Obviously, I haven't set up my count variable so it won't compile but that's the idea of the algorithm. All that's left is initializing count to 0 and being able to pass it between recursive calls. But I'm only allowed the two parameters for this function.
I can, however, write auxiliary functions.
Thoughts?
If SML has support for nested functions you could do like this:
divmod(number : int, divisor : int) =
_divmod(n : int, d : int, count : int) =
if n < d then
(count, n)
else
_divmod(n - d, d, count + 1)
_divmod(number, divisor, 0)
Personally, I like the fact that SML isn't a pure functional language. Keeping track of function calls is naturally done via side effects (rather than explicitly passing a counter variable).
For example, given a generic recursive Fibonacci:
fun fib 0 = 0
| fib 1 = 0
| fib n = fib(n-2) + fib(n-1);
You can modify it so that every time it is called it increments a counter as a side effect:
counter = ref 0;
fun fib 0 = (counter := !counter + 1; 0)
| fib 1 = (counter := !counter + 1; 1)
| fib n = (counter := !counter + 1; fib(n-2) + fib(n-1));
You can use this directly or wrap it up a bit:
fun fibonacci n = (
counter :=0;
let val v = fib n
in
(!counter,v)
end);
With a typical run:
- fibonacci 30;
val it = (2692537,832040) : int * int
(Which, by the way, shows why this version of the Fibonacci recursion isn't very good!)

Prime number check

I'm having some issues with my prime number checker in F#. It doesn't seem to give the right results so I'm guessing I've screwed up the logic somewhere but I can't figure out where. The implementation is a simple brute forcing one so the logic isn't complicated and I've implemented similiar solutions using for loops in imperative languages before.
let rec isPrime iterator (n : int) =
match iterator with
| 1 -> isPrime (iterator + 1) n
| a when a = n -> isPrime (iterator + 1) n
| _ -> match n % iterator = 0 with
| true -> false
| false -> isPrime (iterator + 1) n
As you already figured out in the comments, the problem is that the function should terminate and say true when the iterator reaches n. You can actually make it faster just by iterating up to square root of n or at least n/2 because by the time you reach n/2, you know it will be a prime.
This kind of logic seems to be easier to write using if rather than match - although you can easily fix it by fixing the case in match, I'd probably write something like:
let rec isPrime iterator (n : int) =
if iterator = n / 2 then true
elif iterator = 1 then isPrime (iterator + 1) n
elif n % iterator = 0 then false
else isPrime (iterator + 1) n
Also, you might not want to expose the iterator parameter to the user - you can write the code using a nested function which calls the loop starting with iterator = 2 (and then you don't need the iterator = 1 case at all):
let isPrime (n : int) =
let rec loop iterator =
if iterator = n/2 then true
elif n % iterator = 0 then false
else loop (iterator + 1)
loop 2

Resources