Home > front end >  how to find the range of any given integer by a specified step with recursion
how to find the range of any given integer by a specified step with recursion

Time:03-19

I want to use recursion to find the range of a given integer by a specified step.

  given number --> -20 
  step --> 4
  returns --> [ -20, -16, -12, -8, -4 ]

Thus far, I was able to create a recursive function to return the corresponding results:

function range(num,step,res=[]) {
  const s = num < step ? step : -step; 
  if (num === step   s) return res;
  return num === step ? [...res,num] : range(num s,step,[...res,num]);
}

console.log(range(5,1)); // [ 5, 4, 3, 2, 1 ]
console.log(range(-8,2)); // [ -8, -6, -4, -2, 0, 2 ]
console.log(range(-20,4)); // [ -20, -16, -12, -8, -4 ]

However, the following invocations returns stackoverflow

console.log(range(-7,2)); // stackoverflow!
console.log(range(11,5)); // stackoverflow!

I know something is wrong with the code, but I just couldn't figure out what it is. Can someone kindly point me in the right direction or show me what I'm doing wrong. Million thanks in advance :)

CodePudding user response:

The case range(-7,2) cannot resolve in the current version because it will infinitely step between 1 and 3 (because it's stepping by 2 and trying to arrive at 2, but it's never going to). You can make it give up when it goes past with something like this:

function range(num,step,res=[]) {
    const s = num < step ? step : -step;
    const forward = num   s < step ? true : false;
    if (num === step   s) return res;
    if(forward) {
        return num >= step ? [...res,num] : range(num s,step,[...res,num]);
    }else {
        return num <= step ? [...res,num] : range(num s,step,[...res,num]);
    }

}

CodePudding user response:

This is under the assumption that your goal is to start at the first parameter then step down until the last number is 0, 1, or -1 (basically as close to zero as possible).

First, instead of flip-floping the step to/from neg/pos, convert neg to pos and set a flag for neg steps:

if (num < 0) {
  n = Math.abs(num);
  neg = true;
} else n = num;

Remove this extra step which left no way for odd numbered parameters to stop:

if (num === step s) return res;

The only difference in this line is < instead of ===. That'll take odd numbers closer to 0 and even numbers to zero:

let result = n < step ? [n, ...res] : rangeToZero(n -step, step, [n, ...res]);

Finally, if the neg == true we make each number a negative (it feels like cheating):

if (neg) {
  return result.map(N => -Math.abs(N));
}

function rangeToZero(num, step, res=[]) {
  let n, neg = false; 
  if (num < 0) {
    n = Math.abs(num);
    neg = true;
  } else n = num;

  let result = n < step ? [n, ...res] : rangeToZero(n -step, step, [n, ...res]);
  if (neg) {
    return result.map(N => -Math.abs(N));
  }
  return result;
}

console.log(rangeToZero(5,1)); // [ 5, 4, 3, 2, 1, 0 ]
console.log(rangeToZero(-8,2)); // [ -8, -6, -4, -2, 0 ]
console.log(rangeToZero(-20,4)); // [ -20, -16, -12, -8, -4, 0 ]
console.log(rangeToZero(10, 3)); // [ 10, 7, 4, 1 ]
console.log(rangeToZero(-7,2)); // [ -7, -3, -5, -1 ]
console.log(rangeToZero(11,5)); // [ 11, 6, 1 ]

  • Related