Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mutually recursive functions - exercise not making sense to me

Tags:

javascript

I know this is a silly way to determine even-odd numbers. It is just a lesson in recursion, and probably some other concepts as well.

The problem.

When I follow the logic, it looks like it doesn't matter what value you give "n", it will always eventually equal "0" and always end up "false".

What is going on?

function isOdd(x) {
    return !isEven(x);    
}

function isEven(x) {
    if(x===0) {
        return true;
    } else {
        return isOdd(x-1);
    }
}
like image 443
dwilbank Avatar asked Aug 21 '13 20:08

dwilbank


People also ask

What are mutually recursive functions?

Two functions are called mutually recursive if the first function makes a recursive call to the second function and the second function, in turn, calls the first one.

Do you think that all recursive functions can be rewritten as loops?

Any recursive algorithm can be rewritten to use loops instead. The opposite is also true. Any iterative algorithm can be written in terms of recursion only. expressiveness: some algorithms are just naturally simpler or easier to write with loops.

How do you know if a function is recursive?

If the function requires a previous term in the same sequence, then it is recursive. Note how this function specifically states the beginning two values. Most recursive functions will give you the beginning value or values that are needed to fully calculate the sequence.

Which kind of code can be used to replace recursive function?

Many professional developers probably already know how to replace recursive functions to avoid stack-overflow problems in advance by replacing with iterative function or using stack (heap stack) and while-loop (recursive simulation function).


2 Answers

This is how isOdd returns true on an even number:

When you pass 2 to isOdd, it will forward this to isEven. Your call stack now looks like this (newest function is up):

isEven(2)
isOdd(2)
main

isEven will now call isOdd with 1:

isOdd(1)
isEven(2)
isOdd(2)
main

isOdd will again forward this to isEven:

isEven(1)
isOdd(1)
isEven(2)
isOdd(2)
main

the whole happens again with 0

isEven(0)
isOdd(0)
isEven(1)
isOdd(1)
isEven(2)
isOdd(2)
main

isEven now terminates with true, and the whole call-stack is rewinded. True is returned to isOdd:

isOdd(0)   <-true
isEven(1)
isOdd(1)
isEven(2)
isOdd(2)
main

isOdd will negate the return value, and thus return false to isEven:

isEven(1) <- false
isOdd(1)
isEven(2)
isOdd(2)
main

isEven again returns the result as-is to isOdd

isOdd(1) <- false
isEven(2)
isOdd(2)
main

isOdd negates and returns:

isEven(2) <- true
isOdd(2)
main

isEven returns as-is:

isOdd(2) <- true
main

isOdd negates and returns to main:

main <- false

this is how isOdd returns false on an uneven number:

When isEven terminates, the call-stack looks like that.

isEven(0)
isOdd(0)
isEven(1)
isOdd(1)
main

isOdd receives true:

isOdd(0) <-true
isEven(1)
isOdd(1)
main

isOdd negates:

isEven(1) <- false
isOdd(1)
main

isEven returns the unchanged value:

isOdd(1) <- false
main

isOdd negates and returns to main:

main <- true

So whats the explanation?

The whole trick is that when you have an odd number, there is an even number of negations in the call-stack. When you negate a boolean value an even number of times, it comes out as it was before. When you have an even number, you have an odd number of negations, and the result is changed.

like image 113
Philipp Avatar answered Oct 12 '22 08:10

Philipp


When I follow the logic, it looks like it doesn't matter what value you give "n", it will always eventually equal "0" and always end up "false".

you want to keep in mind how many isOdd are there in the stack trace. for instance: given x = 2

isOdd(2) => !isEven(2) => !(isOdd(1)) => !(!isEven(1)) => !(!(isOdd(0))) => !(!(!isEven(0))) => !(!(!(true)))
like image 44
msr_overflow Avatar answered Oct 12 '22 07:10

msr_overflow