DEV Community

Cover image for The legendary "numeric triangle problem"
Azhari Rizkita
Azhari Rizkita

Posted on

The legendary "numeric triangle problem"

As the title said, I want to solve this much legendary problem as simple as possible. This time I gonna pick JS to solve this problem (although I will pick JS anytime LOL).

Goals

Basically, we need two loops. The first one to generate those "number of rows" (gonna call this the "main loop") and the second one to generate their "siblings" (gonna call this the "inner loop").

The main loop should generate values like this:

**5**
**4**
**3**
**2**
**1**
Enter fullscreen mode Exit fullscreen mode

And the inner loop should complete the first loop like this:

5   **4**   **3**   **2**   **1**   
4   **3**   **2**   **1**   
3   **2**   **1**   
2   **1**   
1   
Enter fullscreen mode Exit fullscreen mode

Code

Here is the code to achieve it

const pyramidize = (maxRows = 5) => {
  // the finalContainer will be our final string output
  let finalContainer = "";
  // say we define the max rows to 5, it means, we will
  // generate 5 lines of numbers.
  for (let currentRow = maxRows; currentRow > 0; currentRow--) {
    // make a new variable to store the current row strings
    let _currentRowContainer = "";
    // to generate the siblings we need to do a for-loop again
    // we will call it an inner-loop with initial index
    // (we will name it as currentSibling) equals to currentRow
    //
    // say the currentRow equals to 5, after the inner for-loop
    // finished you will get
    // 5
    // 4
    // 3
    // 2
    // 1
    for (
      let currentSibling = currentRow;
      currentSibling > 0;
      currentSibling--
    ) {
      // the first iteration (we assume the current row is 5)
      // will produce this string:
      //
      // _currentLevel = "5"
      //
      // the next iteration will be 4, so it will reproduce the
      // _currentLevel like this
      //
      // _currentLevel = "5 4"
      //
      // and so on until _currentLevel = "5 4 3 2 1"
      _currentRowContainer += `${currentSibling}\t`;
    }
    // after the inner-loop finished, simply concat the result
    // into our final container (don't forget to add \n for new line)
    finalContainer += `${_currentRowContainer}\n`;
  }
  return finalContainer;
};
Enter fullscreen mode Exit fullscreen mode

That code is actually a 10-liner code if we simplify the variables like this:

const pyramidize = (n = 5) => {
  let final = "";
  for (let i = n; i > 0; i--) {
    let _temp = "";
    for (let j = i; j > 0; j--) {
      _temp += `${j}\t`;
    }
    final += `${_temp}\n`;
  }
  return final;
};
Enter fullscreen mode Exit fullscreen mode

Playground

For the sake of our laziness, I brought us a codesandbox to mess around:

WARNING: don't put the value higher than 1000 unless you want your browser to crash (will elaborate why this may happen via time complexity). Haha!

Time complexity

Finally the boring part. We gonna see how this code scale.

See the number of iterations for each rows reproduce via the playground console. Here is the formula of the iteration number (n = rows)

(n * (n + 1)) / 2

Simplify the formula, we got:

(n^2 + n) / 2

Since constants don't really matter in complexity measurement, take out the constants and we got this big O notation:

O(n^2)

Although the real calculation can be so much different between the actual formula and the big O notation, here is a simulation on how big the difference is:

Conclusion

The legendary numeric triangle problem can be solved with such a few lines of codes. It is easy to code but sucks to scale. Hope this explanation helps you well!

Top comments (0)