Dell Watson
Dell Watson

Reputation: 367

Recursive javascript function is not working

I'm trying recursion.

I just want the output to be the result of multiplying the input by 2: output = 2*input.

It should be like this, why is it not working?

function fE(f) {
  if(f < 0){
    return 1;}
  else{
  return f + fE(f);}


}

console.log(fE(3)); // output 6
console.log(fE(6)); // 12

Upvotes: 0

Views: 188

Answers (3)

Mulan
Mulan

Reputation: 135227

Great answers from @torazaburo and @nnnnnn – they're practical and should solve your immediate problem. I'll offer some other alternatives in hope that these will help your brain think about recursive procedures in a variety of ways.

Another common recursion technique is using state variables in an auxiliary function

function mult (x, y) {
  function aux (result, counter) {
    if (counter === 0)
      return result
    else
      return aux (result + x, counter - 1)
  }
  return aux (0, y)
}

console.log(mult (5, 4)) // 20

Here's another technique that uses continuation passing style

function multk (x, y, k) {
  if (y === 0)
    k (0)
  else
    multk (x, y - 1, function (result) { k (result + x) })
}

multk (5, 4, function (result) { console.log(result) /* 20 */ })

And here's a nutty boiled down version that uses nothing more than primitive +1 and primitive -1. It may seem complicated but I constructed it for you so that you can see how more complex recursive procedures can be built out of smaller ones. If you can follow this code, it should help you gain a greater understanding of recursion.

(I added some console.log lines so you can get a better visualization of what's happening. You wouldn't want to leave these in your code.)

function add1 (x) {
  return x + 1
}

function sub1 (x) {
  return x - 1
}

function add (x, y) {
  console.log('adding:', x, y)
  if (y === 0)
    return x
  else
    return add (add1(x), sub1(y))
}

function mult (x, y) {
  function aux (result, counter) {
    console.log('multiplying:', result, counter)
    if (counter === 0)
      return result
    else
      return aux (add(result, x), sub1(counter))
  }
  return aux (0, y)
}

console.log('result:', mult (5, 4)) // 20

And the same thing using undelimited continuations

function add1 (x, k) {
  k (x + 1)
}

function sub1 (x, k) {
  k (x - 1)
}

function addk (x, y, k) {
  console.log('adding:', x, y)
  if (y === 0)
    k (x)
  else
    add1 (x, function (x1) {
      sub1 (y, function (y1) {
        addk (x1, y1, k)
      })
    })
}

function multk (x, y, k) {
  function aux (result, counter, k) {
    console.log('multiplying:', result, counter)
    if (counter === 0)
      k (result)
    else
      addk (result, x, function (result1) {
        sub1 (counter, function (counter1) {
          aux (result1, counter1, k)
        })
      })
  }
  aux (0, y, k)
}

multk (5, 4, function (result) { console.log('result:', result) /* 20 */ })

Upvotes: 1

user663031
user663031

Reputation:

Recursion involves a base case, which in your case is an input of zero. The answer in that case is zero. Otherwise, reduce the problem to the sum of two and the result of calling the function recursively with an argument one less. If the input is negative, return the negation of the result of the negation of the input.

function fE(f) {
  if (f === 0) return 0;
  else if (f < 0) return -fE(-f);
  else return 2 + fE(f - 1);
}

console.log(fE(3)); // output 6
console.log(fE(6)); // 12
console.log(fE(-4)); // -8

Your code:

function fE(f) {
  if(f < 0){
    return 1;}
  else{
  return f + fE(f);}
}

has the following problems:

  1. If the input is zero or less, you probably want to return zero, not one.
  2. Otherwise, you want to recurse with a value of one less than the input. fE(f) will cause an infinite loop, right?
  3. You don't want to add f to the result of recursing; you want to add 2, which is where you get the doubling effect.

Upvotes: 3

nnnnnn
nnnnnn

Reputation: 150030

Your function as shown will try to recurse infinitely, because the recursive call on the line with f + fE(f) passes the same value of f through each time, which means the if test on the first line will always fail.

It doesn't make any sense to implement this recursively, because you can calculate the correct result with one line of code:

function fE(f) { return 2 * f; }

Perhaps a better example of a recursive function (for learning purposes) would be a function that multiples any two numbers together via a larger number of recursive calls:

multiply(10, 3)  // return 30

...again that could easily be implemented in one line:

function multiply(a, b) { return a * b; }

...but you could do it with recursion like this:

function multiply(a, b) {
  console.log(a, b);
  if (b === 0)
    return 0;
  else if (b === 1)
    return a;
  else if (b < 0)
    return -multiply(a, -b);
  else
    return a + multiply(a, b-1);
}

multiply(12, 4)  // 48
multiply(5, -3)  // -15
multiply(3, 0)   // 0

Notice that each time the function calls itself it passes a different value in the second argument, so that eventually the else if (b === 1) condition will be true and the recursion will stop. I've included a console.log(a,b) so that you can see for yourself what the arguments are on each call.

Upvotes: 1

Related Questions