function recur(n, cur) {
if (!cur) {
cur = 0;
}
if (n < 2) {
throw new Error("Error");
}
if (n === 2) {
return 1 / n + cur;
}
console.log(n-1);
console.log(cur + 1 / (n * (n-1)));
return recur(n - 1, cur + 1 / (n * (n-1)));
}
const result = recur(5, 5);
console.log(result);
I am seeing the code but I do not understand how the final result gives me 5.8 with those parameters, my analysis is that if the three conditions above are not met, these:
if (!cur) {
cur = 0;
}
if (n < 2) {
throw new Error("Error");
}
if (n === 2) {
return 1 / n + cur;
}
When none of them are met, it calls itself again, passing the same parameters after resolving said operation, that is:
return recur(5 - 1, 5 + 1 / (5 * (5-1))); //primera vez
return recur(4 - 1, 0.3 + 1 / (4 * (4-1))); // segunda vez
and so on until n is equal to 2, but doing it with those parameters gives me 0.68888 at the end, and does not give 5.8
About recursion
Your reasoning is correct except for one mistake, every time the function is called recursively, the second parameter is
cur = cur + (1/(n*(n-1)))
. You say that it should be (in the first iteration) 0.3, but it is5 + 1/5*(5-1)
, this gives you 5.05. Now the new value for cur is 5.05, and so on untiln = 2
. I put a table with the iterations:5 + 1/(5*4) = 5.05
5.05 + 1/(4*3) = 5.13
5.13 + 1/(3*2) = 5.3
Retorno = 1/2 + 5.3 = 5.8
Compare it with the return functions and you will understand.
About operator precedence
Apparently the error of @plus is with the precedence of the operators and not with not understanding the recurrence of the code.
The precedence of operators in an expression tells us which is evaluated first . That is, which operands and with which operator do I solve first. For example:
1 + 2*3 = 7 y no 9
(1+2) * 3 = 9 y no 7
2 * 5^3 = 250 y no 1000
5*3 - 4/2 + 3 = 16
Note: I left a space around some operators and not others, to illustrate more graphically the priority in the operations.
Each language has its own operators and its own precedence rule. In general, there is a certain coincidence in how each language evaluates precedence, especially in basic mathematical operators such as
+ - * / ()
logicaland, not y or
and relational operators== < > !=
, etc.If we want to alter the natural precedence of the operators, we must use parentheses around the expression we want to be evaluated first, since they have the higher precedence. An expression is always evaluated from left to right. For the precedence of mathematical operators, it is good to remember the acronym PEMDSR , which stands for:
That is, first all expressions inside parentheses are evaluated, then all powers, multiplications and so on until last, subtraction. In any case, if we have doubts, it is always good to condition the precedence using parentheses to ensure that we do not have an error there. It's also a good idea to check with a scientific calculator . Although it is better idea to learn it definitively ;-)
So far, in general, for most languages. Specifically for JavaScript, here is a precedence table that you can refer to.
Well, I hope it helps you. Cheers!
Based on some tests and debugging the code I came to the following conclusion:
The final result in all cases tested (for all n positive integers) in the function
recur(n, cur)
, iscur + (n - 1) / n
.Explanation of operation:
The first
if
checks if cur is 0 , null or undefined and if so sets it to 0. I gather it does this in case you want to use the function without passing the cur parameter . Otherwise, it will be undefined and if we were to operate with it, we would receive a NaN .The second
if
, in view of the conclusion we reached (cur + (n - 1) / n
) returns an error, since its operation is not designed for valuesn
less than 2.The third
if
is the last check. Since there is only one case where n is 2 equals 2, we could replace it with:Finally comes the place where the magic happens. Let's understand the expression
recur(n - 1, cur + 1 / (n * (n-1)))
:Here what the function does is call itself.
n - 1
is the prior of n . If n is 5, the next call will be withn = 4
. And it's fine that it is like that since in this case, if n remained constant or increased, we would enter an infinite loop. We then deduce that n is in charge of keeping track and allowing the recursion to come to an end.The receiving parameter is nothing more and nothing less than cur . Having seen this, we realize that cur is the parameter used to carry the information.
As for
cur + 1 / (n * (n-1))
, what it does is add to our variable cur , the inverse of the product ofn
by its previous one.To conclude, I was going to do an analysis like the one done by Juan Pablo but he beat me. Why repeat what someone already did?