const fibonacci = function (n) {
n = parseInt(n)
if (n < 0) return 'OOPS'
if (n < 2) return n
else {
return fibonacci(n - 1) + fibonacci(n - 2)
}
}
this is a recursive function for solving the problem but I am finding it difficult to understand why the base case must evaluate to 1. I get the syntax but I don't get the logic behind the solution.
The base case must evaluate to 1 because the first two terms of the Fibonacci sequence are 1, 1 (or in some cases 0, 1, which gives the same sequence starting with a zero).
Unrelated to your question, but the way you wrote that will be very slow because it will recalculate Fibonacci numbers lower than the target many, many times. If this must be recursive, then use memoization so each value is only calculated once.
Related
I have the following function fn(n).
function fn(n) {
if (n < 0) return 0;
if (n < 2) return n;
return fn(n - 1) + fn(n - 2);
}
I understand how this code works, but don't how to calculate time complexity for it.
Let’s do some examples:
For n = 3, you have 5 function calls. First fn(3), which in turn calls fn(2) and fn(1) and so on.
For n = 4, you have 9 function calls. First fn(4), which in turn calls fn(3) and fn(2) and so on.
Graphical representation of the 2 examples:
The leftmost nodes go down in descending order: fn(4), fn(3), fn(2), fn(1), which means that the height of the tree (or the number of levels) on the tree will be n.
The time complexity of this code is 2^n - 1. Although, if we count all calls will be just 9 calls for n = 4.
And the question is how we get 2^n - 1? I don't understand
One of the ways of calculating recursive algorithm's time complexity is using the Recursion Tree Method. For this particular case, we can write T(n)=T(n-1)+T(n-2)+2*O(1), where O(1) means constant time, since we have two comparison checks of n values using if. The recursion tree would look something like this:
1 n
2 (n-1) (n-2)
4 (n-2) (n-3) (n-3) (n-4)
8 (n-3)(n-4) (n-4)(n-5) (n-4)(n-5) (n-5)(n-6)
...
2^i for i-th level
Total work done will be the sum of all of the work done in each level, so we can write T(n)=1 + 2 + 4 + 8 + 16 + 32 + ... = 2^0 + 2^1 + 2^2 + 2^3 + 2^4 + ... + 2^i. This is a geometric series which means that the T(n) is equal to (1-2^n)/(1-2) = (1-2^n)/(-1) = 2^n - 1. Because of that the time complexity of the function fn(n) is O(2^n).
You could also approach this using Back Substitution method. We know the following:
T(0)=1
T(1)=1
T(2)=1
T(n)=T(n-1)+T(n-2)+2*O(n)≈2*T(n-1)
Substituting T(n-2) with T(n-1) is allowed. In doing so you will get a higher bound which is still true for T(n-1)+T(n-2).
After the substitution you can also write T(n-1)=2*T(n-2), T(n-2)=2*T(n-3), ...
Using these values and substituting them recursively in to the T(n) you will get:
T(n)=2*2*T(n-2)
=2*2*2*T(n-3)
=2*2*2*2*T(n-4)
=...
=2^i * T(n-i)
From there you can write n-i=1 => i=n-1 and substitute the i value in T(n). You can do this because T(1)=1 is one of the base conditions.
=> T(i)=2^(n-1) * T(n-(n-1))=2^(n-1) * T(n-n+1)=2^(n-1) * T(1)=2^(n-1)
This means that the time complexity is O(2^n).
In the example below, I don't want to make a counter as a param. Rather, I just want to return '+ 1' each time so that what gets returned is the number of steps it takes. My issue lies with the base case. If I do return + 1, I get the correct number of steps plus one additional step so I tried just return but that delivers NaN. Is it even possible?
var numberOfSteps = function(num) {
if (num == 0) {
return;
} else {
if (num % 2 == 0) {
return 1 + numberOfSteps(num/2);
} else {
return 1 + numberOfSteps(num - 1);
}
}
};
edit : The goal is to track how many steps it takes to reduce a number to 0. If it's even, divide by 2 or else subtract by 1. Ultimately, I want to return the number of steps it takes for any given number to get reduced to 0 following those rules
I hope the point has gotten through in the long comment thread and other answers that return + 1 is equivalent to return (+1), that is, return the integer positive one. And since there are no steps to take once you've reached zero, +1 is the wrong answer. Similarly, a plain return is functionally equivalent to return undefined. But undefined is not a number, and you're going to run into problems if you later try to add 1 to it. So the solution from the comments or other answers to return the correct number of steps, which in this case 0, will fix your code.
I would like to point out another way to solve this, though:
const numberOfSteps = (n) =>
n <= 0
? 0
: 1 + numberOfSteps (n % 2 == 0 ? n / 2 : n - 1)
console .log (numberOfSteps (12))
There are superficial differences here from the other solutions, such as using an arrow function, using a conditional statement (ternary) rather than if-statements, and using <= 0 instead of < 0 to avoid possible infinite loops on negative numbers.
But the fundamental difference is that this code only has one recursive branch. I think this is a better match to the problem.
We can think of this as a function which answers "How many steps does it take to reach 0 from our input number if each step cuts even numbers in half and subtracts one from odd ones?" Well that logically leads to a base case (we're already at 0) so have to return 0, and a recursive one (we're at some positive integer) so have to add 1 to the total steps required from our next entry.
By doing this single recursive call and adding one to the result, we make it clearer what the recursion is doing.
If this is unclear, then this alternative might show what I mean:
const takeStep = (n) =>
n % 2 == 0 ? n / 2 : n - 1
const numberOfSteps = (n) =>
n <= 0
? 0
: 1 + numberOfSteps (takeStep (n))
Think you just need to return 0 when it's...zero.
var numberOfSteps = function(num) {
if (num == 0) {
return 0;
} else {
if (num % 2 == 0) {
return 1 + numberOfSteps(num/2);
} else {
return 1 + numberOfSteps(num - 1);
}
}
}
return + 1 maybe doesn't do what you think it does: it returns the number 1. + here means positive not negative, there is no addition or subtraction going on. It will also give you one too many steps.
return; by itself returns undefined, which when converted to a Number, translates to NaN, because, well, it's not a number.
I am trying to count TRAILING zeros from a recursive manner. Basically I split the final recursive result and then created a var counter that will count all the zeros.
function countingZeros(n) {
if (n < 0) {
// Termination condition to prevent infinite recursion
return;
}
// Base case
if (n === 0) {
return 1;
}
// Recursive case
let final = n * countingZeros(n -1);
let counter = 0;
String(final).split('').forEach(function(item){
item === 0 ? counter++ : counter;
});
return counter;
}
countingZeros(12) // => suppose to output 2 since there are 2 trailing zeros from 479001600 but got 0
countingZeros(6) // => suppose to get 1 since 720 is the final result.
I am expecting to get 2 in return as the counter must return but instead I got 0. Any idea what am I missing on my function? How should I fix it?
I think you're working too hard. First of all, in response to a comment, you don't actually need to calculate the factorial, since all you really need is to count factors of 5 and of 2. And since there are many more factors of 2, your real answer is just counting factors of 5. But each factor of 5 must be a factor of one of {1, 2, 3, ... n}, so we just have to add up the highest powers of five that evenly divide into each of {1, 2, 3, ... n}.
We can do that with some simple recursion:
const fiveFactors = (n, acc = 0) => (n % 5 == 0)
? fiveFactors(n / 5, acc + 1)
: acc
const factZeros = (n, acc = 0) => (n > 0)
? factZeros(n - 1, acc + fiveFactors(n))
: acc
factZeros(1000) //=> 249
Note that both functions are eligible for tail-call optimization.
Also, although this does involve a double recursion, it's not really ill-performant. Four out of five times, the internal recursion stops on the first call, and of the remainder, four out of five stop on the second call, and so on.
You are trying to count the number of zeroes using string functions(i will assume, you forgot to include the factorial method. Correct flow could have been- you first pass the input to a factorial method and pass output from factorial method to countingZeros method). Anyways as stated already in other answer, you don't really need to calculate the factorial product to count the trailing zeroes.
Here a sample to count the number of trailing zeroes in n!
temp = 5;
zeroes = 0;
//counting the sum of multiples of 5,5^2,5^3....present in n!
while(n>=temp){
fives = n/temp;
zeroes = zeroes + fives;
temp = temp*5;
}
printf("%d",zeroes);
Note that each multiple of 5 in the factorial product will contribute 1 to the number of trailing zeros. On top of this, each multiple of 25 will contribute an additional 1 to the number of trailing zeros. Then, each multiple of 125 will contribute another 1 to the number of trailing zeros, and so on.
Here's a great link to understand the concept behind this:
https://brilliant.org/wiki/trailing-number-of-zeros/
I try to implement the Lucas–Lehmer test (LLT) primality test for Mersenne numbers (https://en.wikipedia.org/wiki/Lucas%E2%80%93Lehmer_primality_test). It should be polynomial and hence fast. Here is my code:
function countPrimeNumberWithDigits(numberOfDigits)
{
if(numberOfDigits < 1)
{return "Please give a valid input!";}
var shouldBeMoreThanThis = Math.pow(10, numberOfDigits-1), n = 3, M = countMWithIndex(n);
while(M < shouldBeMoreThanThis)
{
n += 2;
M = countMWithIndex(n);
}
console.log(n);
while(true)
{
var S = 4, k = 1;
M = countMWithIndex(n);
while(k != n - 1)
{
S = (S*S - 2)%M;
k +=1;
}
if(S!=0)
{n+=2;}
else
{break;}
}
return "Prime number: " + countMWithIndex(n);
}
function countMWithIndex(n)
{return Math.pow(2, n) - 1;}
Here is attempt to use the algorithm implemented above:
https://oobarbazanoo.github.io/findPrimeNumberWithSpecifiedQuantumOfDigits/
When I try number of digits which is less than 7 everything is okay, but when I try to ask for prime number with at least 7 digits the program just stumbles and doesn`t give an answer.
Please, help me. What is wrong with my algorithm implementation or what is wrong with my program itself?
If I run the code on https://repl.it/languages/javascript with this change:
S = (S*S - 2 + M)%M;
Then it finishes for (seemingly) any number of digits. However, the results seem incorrect: it outputs non-primes with more digits than requested.
The problem is that javascript can evaluate modulo to negative results. For example, -2 % 5 will be -2. This is mathematically correct, but most computer science algorithms require positive values, so 3 in this case.
Adding M in that formula will ensure that the result is positive regardless of language quirks.
The problem with incorrect results is likely due to the fact that you do not follow this requirement:
The Lucas–Lehmer test works as follows. Let Mp = 2**p − 1 be the Mersenne number to test with p an odd prime.
The p there is the n in your code. Nowhere do you ensure that n is prime.
Then there is also that javascript's integer type might not be big enough. With n larger than 23, it starts to reach its limits. For example, there is no Mersenne prime with 7 digits. The next is with 10 digits, which is 2**31 - 1.
You won't be able to find it in (pure) javascript however, because the computation involves squaring 2**31 - 1, which exceeds the bounds of javascript's integers.
I'm reading a JavaScript book, I'm new at this, so I got to the part of recursion and I get how recursion works but is not that part is hard to me is the math part.
This is the code:
function isEven(n) {
if (n == 0)
return true;
else if (n == 1)
return false;
else if (n < 0)
return isEven(-n);
else
return isEven(n - 2);
}
lets say I pass to the function 50 as a value right
isEven(50);
That give me true... how come 50 == 0 is true or 75 == 1 is false... I really don't get it.
When you pass 50 to this function, it goes to the last block (else) and is executed recursively. When you write return isEven(n - 2);, you execute isEven(48), and then the next time isEven(46) and so on right upto the point where you reach isEven(0).
This calls the first if block and you get true as your output. The true is returned by isEven(0), followed by isEven(2) (becuase when you executed isEven(2) you ended up going to return isEven(0)) and this bubbles up the stack to finally return the output of isEven(50) as true.
This code is kind of a long way of checking whether a number is even. It relies on the fact that if a number is even and you continually subtract 2 from it, you'll eventually reach 0. Otherwise, if your number is odd, subtracting 2 repeatedly will eventually reach 1.
So if the number you pass is greater than 0, it will send the next number (n - 2) back to the function again, until it either reaches 0 or 1. Then we stop.
If the number is negative, we just flip the sign and do the same process.
This is an interesting way of applying recursion to an issue that could be solved as simply as:
return n % 2 == 0
Basically, it works by having two base cases: n == 0 and n == 1. Both of these are "known", so they just return true or false. If the number is negative, do a recursive call with the sign reversed (isEven(-n)). Otherwise, you just subtract 2 (isEven(n - 2)). This works because any odd number minus 2 is still an odd number, and even number minus 2 is still even. So, you simply keep subtracting 2 from n until n fits one of the base cases (n == 0 or n == 1).
if (n == 0) // base case
return true;
else if (n == 1) // base case
return false;
else if (n < 0) // reverse sign, call recursively
return isEven(-n);
else // default, subtracts 2, calls recursively
return isEven(n - 2);
Use this tool to visualize your code and you'll see where you're getting hung up.
Click the Forward > button after the page loads to step through your code.
You can simplify the function by using % operator
let isEven = n => !(n % 2);