Is my understanding of this JS algo correct?

As part of my solution to a project I’m working on, I came across an algorithm on SO that does exactly what I want it to (generate an array of all possible variants from [0, 0, 0] up to the max value in each index position, for example [2, 1, 3]).

My issue is that due to the complex logic of the solution, I’m not entirely sure if I understand how it works. What I’ve done is annotated it with my own notes, and would like to submit those for review by the community here.

I feel like I more or less get the gist but have a feeling that I’m missing some subtleties that may in fact be quite important – but that’s just my hunch; you tell me if I’m wrong :slight_smile:

Original answer: https://stackoverflow.com/a/14001422/14347717

(I’ve made two changes to the linked answer as I express it below: I changed the variable names for enhanced readability, and I wrapped the solution in a parent function that returns a 2D array of all iterations. The actual logic of generating the iterations remains unchanged; the only difference is that I’ve annotated them with comments and this is the part I am looking for feedback on.)

function getIterations(iterNums, iterBase) {

  const nums = iterNums
  // set a base to the 2nd arg; if no 2nd arg, create an array of 0's equal to nums.length
  const base = iterBase ? iterBase : Array.from(Array(nums.length), () => 0)

  // initialize an empty 2D array of iterations
  const iterations = []

  function step() {
    let incomplete = false

    // check if any value in nums is greater than base;
    // if so, it means `step` process is incomplete;
    // in this case, return false
    for (let i = 0; i < base.length; i++) {
      incomplete = incomplete || (base[i] < nums[i])
      if (incomplete) break;
    }
    // "if complete (incomplete === false) return false"
    // this turns `processing` to false and breaks the while loop
    if (!incomplete) return false;

    // run this loop while `step` is `incomplete`
    for (let j = 0; j < base.length; j++) {
      // check if `base` idx is less than nums 
      if (base[j] < nums[j]) {
        // if so, increment the index of base by one;
        // exit loop by returning true;
        base[j]++

        return true
      } else {
        // reset value of base[j] once increments are complete on a given index
        // 'continue' to next increment in loop
        base[j] = 0
        continue // nothing changes when this is commented out but it helps explain logic:
        // when idx value reaches max, it "continues" to the next index position, saying:
        // increment the first value up to max, at which point the ~next~ index increments
        // until the entire array has incremented and gets caught by `if incomplete` check
      }
    }
  }

  let processing = true
  while (processing) {
    processing = step()
    if (processing) iterations.push([...base])
  }

  // this will log the output per OP's intention
  console.log(iterations)

  // this will (when uncommented) return a 2D array of all iterations
  return iterations
}

getIterations([2, 1, 3])

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.