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
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!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.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