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);
}
}
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.
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.
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.
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).
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
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
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.
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)))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With