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 <stdio.h>
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 <stdio.h>
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
Top comments (0)