Pattern Programming — You Are Doing It Wrong!

Half star pyramid is the most common pattern which we come across while writing code to print patterns in any language.

Take a look at this pattern:-

*
**
***
****
*****

One approach that might come to mind is “ the number of stars in each row is equal to the number of row (I mean index of row)”.

Example:- First row have one star, second row have two star, third row have three star, and so on.


const LeftTrianglePattern = (n) => {
  for (let i = 0; i < n; i++) {
    let row = "";
    for (let j = 0; j < i; j++) {
      row += "*";
    }
    console.log(row);
  }
};

Here we are running the external loop N times and the internal loop i (row index) times.

For this particular problem, things go well with this approach. But with complex patterns, it might get confusing.

What’s Wrong Here In This Approach?

Here we are assuming that each row has only stars and there is a line break after the last star. Also assuming that stars in a row are dependent on row index (i).

This is what becomes a big obstacle when patterns become like this:-

    *
**
***
****
*****

or this:-

     *
**
* *
* *
* *
******

In these scenarios, the above mental model doesn’t work well.

The better way to think!

Imagine patterns as a box or matrix of NxN. To create an NxN matrix, both external and internal loops must iterate N times. (See exception in pyramid part).

And instead of depending on the index of the row, try to find a relationship between rows and columns. 

 In other words, try to find how the pattern is related to row i and column j. Then come up with a formula or condition for when to print the star.

Note: There are some cases where depending on the row index works better. 

Example:- Let’s take the same first pattern with which we started our discussion and view it as a matrix. But this time, we will not ignore spaces. 

For proper contrast, let us take space as a pound symbol.

*####
**###
***##
****#
*****

Now it looks like Matrix or what I call — a box!

Let’s try to find a pattern between rows, columns, and stars here:-

  1. The diagonal of this matrix has stars. ie. if i===j then we print a star.
  2. If row index i is greater than column index j. ie. if i>j then print star.

Now we can ready to write code for it:-

// Javascript Approach

const LeftTrianglePattern = (n) => {
  console.log("Left Triangle Pattern");
  for (let i = 0; i < n; i++) {
    let row = "";
    for (let j = 0; j < n; j++) {
      if (i >= j) row += "*";
      else row += " ";
    }
    console.log(row);
  }
};


// Java Approcah (will not work in browser - only for node)
const LeftTrianglePattern2 = (n) => {
  console.log("Left Triangle Pattern 2");
  for (let i = 0; i < n; i++) {
    for (let j = 0; j < n; j++) {
      if (i >= j) process.stdout.write("*");
      else process.stdout.write(" ");
    }
    process.stdout.write("\n");
  }
};


LeftTrianglePattern(6);
console.log("\n\n\n");
LeftTrianglePattern2(6);
console.log("\n\n\n");

Pattern Programming Examples With Explanation

Now let us go through some more patterns,

  1. Hollow Square Pattern
******
*    *
*    *
*    *
*    *
******

Conditions to print star:-

  1. In the first row and first column.
  2. In the last row and last column.
// Javascript Approach

const HollowSquare = (n) => {
  for (let i = 0; i < n; i++) {
    let row = "";
    for (let j = 0; j < n; j++) {
      if (i == 0 || j == 0 || i == n - 1 || j == n - 1) row += "*";
      else row += "#";
    }
    console.log(row);
  }
};

// Java Approcah (will not work in browser - only for node)
const HollowSquare2 = (n) => {
  for (let i = 0; i < n; i++) {
    for (let j = 0; j < n; j++) {
      if (i == 0 || j == 0 || i == n - 1 || j == n - 1)
        process.stdout.write("*");
      else process.stdout.write("#");
    }
    process.stdout.write("\n");
  }
};

2. Square Box

******
******
******
******
******
******

Unconditionally print stars.


// Javascript Approach
const SquareStarPattern = (n) => {
  for (let i = 0; i < n; i++) {
    let row = "";
    for (let j = 0; j < n; j++) {
      row += "*";
    }
    console.log(row);
  }
};

// Java Approcah (will not work in browser - only for node)
const SquareStarPattern2 = (n) => {
  for (let i = 0; i < n; i++) {
    for (let j = 0; j < n; j++) {
      process.stdout.write("*");
    }
    process.stdout.write("\n");
  }
};

3. Right Triangle Pattern

     *
**
***
****
*****
******
right triangle pattern mind map

Conditions to print star:-

  1. If i+j === n-1 (remember we are starting ia dn j from 0) — antidiagonal condition
  2. In the last row and last column.
  3. If i=j > n-1

In short, (i + j === n — 1 || i === n — 1 || j === n — 1 || i + j > n — 1) 


const RightTrianglePattern = (n) => {
  console.log("Right Triangle Pattern");
  for (let i = 0; i < n; i++) {
    let row = "";
    for (let j = 0; j < n; j++) {
      if (i + j >= n - 1 || i === n - 1 || j === n - 1)
        row += "*";
      else row += "#";
    }
    console.log(row);
  }
};

const RightTrianglePattern2 = (n) => {
  console.log("Right Triangle Pattern 2");
  for (let i = 0; i < n; i++) {
    for (let j = 0; j < n; j++) {
      if (i + j >= n - 1 || i === n - 1 || j === n - 1)
        process.stdout.write("*");
      else process.stdout.write("#");
    }
    process.stdout.write("\n");
  }
};

4. Hollow Right Triangle Pattern

     *
**
* *
* *
* *
******

I agree this one looks complicated but if properly understood last on then this one should be a piece of cake. 

Conditions:- Same as last time but remove the last condition (ie. i+j>n)


const HollowRightTrianglePattern = (n) => {
  console.log("Hollow Right Triangle Pattern");
  for (let i = 0; i < n; i++) {
    let row = "";
    for (let j = 0; j < n; j++) {
      if (i + j === n - 1 || i === n - 1 || j === n - 1) row += "*";
      else row += "#";
    }
    console.log(row);
  }
};

const HollowRightTrianglePattern2 = (n) => {
  console.log("Hollow Right Triangle Pattern 2");
  for (let i = 0; i < n; i++) {
    for (let j = 0; j < n; j++) {
      if (i + j === n - 1 || i === n - 1 || j === n - 1)
        process.stdout.write("*");
      else process.stdout.write("#");
    }
    process.stdout.write("\n");
  }
};

5. Hollow Left Triangle Pattern

*
**
* *
*  *
*   *
******

Conditions:- first column and last row along with diagonal.


const HollowLeftTrianglePattern = (n) => {
  console.log("Hollow Left Triangle Pattern");
  for (let i = 0; i < n; i++) {
    let row = "";
    for (let j = 0; j < n; j++) {
      if (i === n - 1 || j === 0 || i === j) row += "*";
      else row += "#";
    }
    console.log(row);
  }
};

const HollowLeftTrianglePattern2 = (n) => {
  console.log("Hollow Right Triangle Pattern 2");
  for (let i = 0; i < n; i++) {
    for (let j = 0; j < n; j++) {
      if (i === n - 1 || j === 0 || i === j) process.stdout.write("*");
      else process.stdout.write("#");
    }
    process.stdout.write("\n");
  }
};

6. The Great Pyramid

Remember we mentioned that both loops should run N times? 

However in some cases, where our pattern is rectangular then the internal loop can be just a function of N.

#####*#####
####***####
###*****###
##*******##
#*********#
***********

Rows => 6 => N
Colums => 11 (2*6 - 1) => 2N -1

Here internal loops will run 2N-1 times
star pyramid pattern trick

Conditions:-

  1. For i=0 row, print a star for (n-1+0)th column.
  2. In i=1 row, print stars for columns n-1–1, n-1, and n-1+1.
  3. For i=2 row, print stars for column n-1–2, n-1–1, n-1, n-1+1, n-1+2

So we can generalize that, print star if the value of j falls between n-1-i and n-1+i.


const PyramidPattern = (n) => {
  console.log("Pyramid Pattern");
  for (let i = 0; i < n; i++) {
    let row = "";
    for (let j = 0; j < 2 * n - 1; j++) {
      if (j >= n - 1 - i && j <= n - 1 + i) row += "*";
      else row += "#";
    }
    console.log(row);
  }
};

const PyramidPattern2 = (n) => {
  console.log("Pyramid Pattern 2");
  for (let i = 0; i < n; i++) {
    for (let j = 0; j < 2 * n - 1; j++) {
      if (j >= n - 1 - i && j <= n - 1 + i) process.stdout.write("*");
      else process.stdout.write("#");
    }
    process.stdout.write("\n");
  }
};

7. Inverted Pyramid

***********
*********
*******
*****
***
*
inverted star pattern

Conditions:- 

  1. For i=0, print star for value of j in the range n-1–3 to n-1+3
  2. For i=1, print star for value of j in the range n-1–2 to n-1+2
  3. For i=2, print star for value of j in the range n-1–1 to n-1+1
  4. For i=3, print star for value of j in the range n-1–0 to n-1+0

So the range of j this time is n-1-(n-1-i) to n-1+(n-1-i).


const InvertedPyramidPattern = (n) => {
  console.log("Inverted Pyramid Pattern");
  for (let i = 0; i < n; i++) {
    let row = "";
    for (let j = 0; j < 2 * n - 1; j++) {
      if (j >= n - 1 - (n - 1 - i) && j <= n - 1 + (n - 1 - i)) row += "*";
      else row += " ";
    }
    console.log(row);
  }
};

const InvertedPyramidPattern2 = (n) => {
  console.log("Inverted Pyramid Pattern 2");
  for (let i = 0; i < n; i++) {
    for (let j = 0; j < 2 * n - 1; j++) {
      if (j >= n - 1 - (n - 1 - i) && j <= n - 1 + (n - 1 - i))
        process.stdout.write("*");
      else process.stdout.write("#");
    }
    process.stdout.write("\n");
  }
};

8. Diamond Pattern

     *
***
*****
*******
*********
***********
***********
*********
*******
*****
***
*

Just combine both pyramids:-

const DiamondPattern = (n) => {
PyramidPattern(n);
InvertedPyramidPattern(n);
};

9. Hollow Star Pyramid

     *
* *
* *
* *
* *
***********

Similar condition like pyramid pattern (no.6) but not range this time.

const HollowPyramidPattern = (n) => {
  console.log("Hollow Pyramid Pattern");
  for (let i = 0; i < n; i++) {
    let row = "";
    for (let j = 0; j < 2 * n - 1; j++) {
      if (j == n - 1 - i || j == n - 1 + i || i == n - 1) row += "*";
      else row += " ";
    }
    console.log(row);
  }
};

const HollowPyramidPattern2 = (n) => {
  console.log("Hollow Pyramid Pattern 2");
  for (let i = 0; i < n; i++) {
    for (let j = 0; j < 2 * n - 1; j++) {
      if (j == n - 1 - i || j == n - 1 + i || i == n - 1)
        process.stdout.write("*");
      else process.stdout.write("#");
    }
    process.stdout.write("\n");
  }
};

10. Hollow Diamond

     *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
*

Require some minor modifications in the pyramid code.

const HollowDiamondPattern = (n) => {
  console.log("Hollow Diamond Pattern");
  for (let i = 0; i < n; i++) {
    for (let j = 0; j < 2 * n - 1; j++) {
      if (j == n - 1 - i || j == n - 1 + i) process.stdout.write("*");
      else process.stdout.write(" ");
    }
    process.stdout.write("\n");
  }
  for (let i = 0; i < n; i++) {
    for (let j = 0; j < 2 * n - 1; j++) {
      if (j == n - 1 - (n - 1 - i) || j == n - 1 + (n - 1 - i))
        process.stdout.write("*");
      else process.stdout.write(" ");
    }
    process.stdout.write("\n");
  }
};

11. Alphabet Patterns

The same logic can be used to print all alphabet using pattern programming. Check out this repo for more:- https://github.com/TrickSumo/Pattern-Alphabet

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.