You know that rush when you finally figure something out after banging your head against a wall for hours? That was me trying to solve a deceptively simple-looking pattern problem in C.

Here’s the challenge:
Problem:
Given a number n, print a (2n-1) x (2n-1) square pattern where the numbers decrease in layers towards the center.

For example, if n = 4, the output should look like this:

4 4 4 4 4 4 4
4 3 3 3 3 3 4
4 3 2 2 2 3 4
4 3 2 1 2 3 4
4 3 2 2 2 3 4
4 3 3 3 3 3 4
4 4 4 4 4 4 4

🧠 Step 1: Overthinking the Basics

First, I tried to figure out the number of rows and columns. You’d think that’s obvious—it’s just 2*n - 1—but I spent way longer than I should have on that. (We all have our moments.)

Once I had that, I did the obvious thing: print a square of that size filled with n.

#include 
int main(){
    int n;
    scanf("%d", &n);
    for(int i = 1; i <= (2*n) - 1; i++){
        for(int j = 1; j <= (2*n) - 1; j++){
            printf("%d ", n);
        }
        printf("\n");
    }
    return 0;
}

Output? A big block of the number n. Cool... but very wrong.

🧱 Step 2: Brute Force Attempts

Then came a new idea: check manually which layer a position falls into and print accordingly. For n = 2, I hardcoded the edges:

int n;
scanf("%d", &n);
for(int i=1; i <= (2*n) - 1; i++){
    for(int j=1; j <= (2*n) - 1; j++){
        if((i==1 || i==(2*n)-1) || (j==1 || j==(2*n)-1)){
            printf("%d ", n);  
        } else {
            printf("%d ", n-1);
        }
    }
    printf("\n");
}

It worked... but only for n=2.

So I extended it manually:

else if((i==2 || i==(2*n)-2) || (j==2 || j==(2*n)-2)) { printf("%d ", n-1); }
else if((i==3 || i==(2*n)-3) || (j==3 || j==(2*n)-3)) { printf("%d ", n-2); }
// and so on...

It started getting messy—really messy. It wasn’t scalable, elegant, or fun anymore.

✨ Step 3: The Breakthrough — It’s Just the Distance from the Edge!

After a ton of brainstorming and frustration, I had a click moment — and it wasn’t from any tutorial or AI assistant. Nobody spelled it out clearly.

I realized: The number we print is just the distance from the nearest edge, subtracted from n.
Not “layers,” not “boundaries,” not “top-left-bottom-right calculations” — just pure distance from the nearest edge.

That’s it.

Let me break it down.

Imagine standing at any position in the square. Ask yourself:
“How close am I to any edge?”

Take the minimum of these:

Distance from the top → i

Distance from the left → j

Distance from the bottom → size - 1 - i

Distance from the right → size - 1 - j

That minimum value is your depth into the square.
And then the number to print is just:
n - depth

Here’s the full code again with this mindset:

#include 
int main(){
    int n;
    scanf("%d", &n);
    int size = (2 * n) - 1;

    for(int i = 0; i < size; i++){
        for(int j = 0; j < size; j++){
            // calculate distance from all four edges
            int top = i;
            int left = j;
            int bottom = size - i - 1;
            int right = size - j - 1;

            // get the minimum distance = depth into the square
            int distance = top;
            if (left < distance) distance = left;
            if (bottom < distance) distance = bottom;
            if (right < distance) distance = right;

            // now subtract from n to get the number to print
            printf("%d ", n - distance);
        }
        printf("\n");
    }
    return 0;
}

💡 Why This Realization Mattered

All the online explanations talked in abstract terms: “layers,” “rings,” “boundaries,” etc.
But none said the simplest, clearest truth:

You're just printing numbers based on how close you are to the nearest edge.

Once I saw it that way, the logic felt natural — like peeling an onion, one layer at a time.

🧠 A Few Little Things I Learned Along the Way

  1. Why bottom = size - i - 1 instead of size - i.
    This tripped me up at first — but it’s because array (or loop) indexing starts at 0. So the last row isn’t at index size, it’s at index size - 1. That -1 matters more than you'd think!

  2. Why I used multiple if conditions instead of else if
    When calculating layer, we need to find the minimum distance to any edge — top, left, bottom, or right. That means we have to compare all four and keep the smallest one. If I had used else if, it would've skipped checking some of them. Using plain if ensures each comparison is made.

  3. If the pattern was based on a fixed n (already given) rather than dynamic positioning, it would’ve been easier to brute-force with an if-else block like I did earlier. That approach just doesn't scale well or adapt cleanly to any n, which is why understanding the "distance from the edge" concept changed everything.

🧠 More Questions That Use This Approach

  • Distance from Center Grid Pattern
  • Square Frame Numbers Pattern
  • Spiral Matrix Generation
  • Pattern with Border and Diagonals
  • Diamond Number Pattern
  • Layered Star Pattern
  • Grid with Center Highlighted
  • Hollow Square with Layers
  • Symmetric Number Pyramid in a Square Grid