Shape Rule
Hollow border
Only cells on the border print numbers — top, right, bottom, and left sides use different counter sequences.

Program 59 prints a hollow square border: a 5×5 grid where only the boundary shows consecutive numbers 1–16 and the inside stays blank — a shift from Program 58’s diagonal diamond to rectangular border logic. This tutorial covers border detection, fixed-width formatting, separate side counters, a live preview, worked C++ examples, edge cases, and complexity.
Hollow border
Only cells on the border print numbers — top, right, bottom, and left sides use different counter sequences.
i, j = 1..5
for (i = 1; i <= 5; i++) for (j = 1; j <= 5; j++) — visit every cell in the 5×5 grid.
if / else if
i == 1, j == 5, i == 5, j == 1 — detect which side of the border the cell belongs to.
k, l, m
k = 6 (right), l = 13 (bottom), m = 16 (left) — track values for non-top sides.
setw(3)
cout << setw(3) << value and " " for inner cells — columns stay aligned.
Complexity
Every cell in the n×n grid is visited once — total work grows as O(n²).
A hollow square border number pattern prints consecutive numbers only on the boundary of a square grid, leaving the interior blank. For a 5×5 square, the top row shows 1..5, the right column continues 6..9, the bottom row shows 13..9, and the left column finishes with 16..13.
In C++ use nested loops over rows and columns, then branch with if / else if to detect border sides. Use cout << setw(3) << value for numbers and three spaces for inner cells.
It bridges Program 58’s diagonal symmetry to rectangular grids — combining border detection, multiple counters, and fixed-width formatting.
i == 1 prints j (1..5).
j == 5 prints k++ (6..9).
Program 58 uses diagonal mirror loops; Program 59 uses rectangular border checks.
Follow Program 58; continue to Program 60 next.
In short: nested i, j loops, border if checks, counters k, l, m, fixed width 3, then cout << "\n" per row.
Print a 5×5 hollow square where the border shows numbers 1–16 clockwise and inner cells are blank spaces of width 3.
// 5×5 hollow border (numbers 1..16)
//1 2 3 4 5
//16 6
//15 7
//14 8
//13 12 11 10 9 | Item | Type | Description |
|---|---|---|
| Grid size | int | 5×5 in the fixed demo — 25 cells total, 16 on the border. |
i (outer) | int | Row index — runs 1 to 5. |
j (inner) | int | Column index — runs 1 to 5. |
k | int | Right column counter — starts at 6, increments. |
l | int | Bottom row counter — starts at 13, decrements. |
m | int | Left column counter — starts at 16, decrements. |
init k, l, m for right, bottom, left sides
for i from 1 to n:
for j from 1 to n:
if top row: print j
else if right column: print k++
else if bottom row: print l--
else if left column: print m--
else: print three spaces
print newline | Approach | Idea | Best for |
|---|---|---|
| if / else if chain | Detect top, right, bottom, left border per cell | Learning and interviews |
| Separate counters | k, l, m for non-top sides | Clockwise numbering |
| Fixed-width format | setw(3) for numbers, " " inside | Aligned columns |
| Configurable size | Read n from input | Flexible grid size |
| Compact trace | n = 3 on paper first | Quick dry-runs before 5×5 demo |
| Goal | Pattern |
|---|---|
| Outer loop | for (i = 1; i <= 5; i++) |
| Inner loop | for (j = 1; j <= 5; j++) |
| Top row | if (i == 1) cout << setw(3) << j; |
| Right column | else if (j == 5) cout << setw(3) << k++; |
| Bottom row | else if (i == 5) cout << setw(3) << l--; |
| Left column | else if (j == 1) cout << setw(3) << m--; |
| Inner cell | else cout << " "; |
| Program 58 contrast | Program 58 uses diagonal mirror; Program 59 uses rectangular border checks |
Same hollow border idea — three ways to set grid size and trace the logic.
n = 5Numbers 1–16 on border
cin >> nRead square size from console
n = 39-cell grid dry-run
i == 1Print column index j
" "Three spaces, width 3
Reach for this pattern when teaching 2D grids, border detection, fixed-width formatting, and multiple counters.
Natural follow-up after Program 58’s diamond — introduces rectangular grids and border-only printing.
Fixed-width setw(3) keeps columns aligned — essential for multi-digit borders.
Separate k, l, m for right, bottom, left — concrete state-tracking practice.
Compare this hollow border with the next pattern in the series.
This is a console teaching pattern — not how you build modern app screens.
Key benefit: one small program that locks in border checks, formatting, and O(n²) grid thinking.
Choose row count between 3 and 9 and draw the centered hollow square border number pattern in the browser.
Three complete C programs — fixed 5×5 border, configurable size, and a compact 3×3 trace demo. Click View Output to reveal sample console results.
Print a 5×5 hollow border with numbers 1–16 clockwise — top, right, bottom, and left sides with separate counters.
Hard-coded grid — use if / else if to detect border sides and setw(3) formatting for alignment.
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
int i, j;
int k = 6, l = 13, m = 16;
for (i = 1; i <= 5; i++) {
for (j = 1; j <= 5; j++) {
if (i == 1)
cout << setw(3) << j;
else if (j == 5)
cout << setw(3) << k++;
else if (i == 5)
cout << setw(3) << l--;
else if (j == 1)
cout << setw(3) << m--;
else
cout << " ";
}
cout << "\n";
}
return 0;
} Row 1 prints j for every column. Rows 2–4 print m-- on the left, k++ on the right, and spaces inside. Row 5 prints l-- across the bottom.
Read square size from the console with safe parsing.
Read n with cin >> n (check cin.fail()) — print column index on border cells, spaces inside. Counter rules can be customized for larger grids.
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
int n, i, j;
cout << "Enter square size (n): ";
cin >> n;
if (cin.fail() || n < 2) {
cout << "Please enter an integer >= 2.\n";
return 1;
}
for (i = 1; i <= n; i++) {
for (j = 1; j <= n; j++) {
int isBorder = i == 1 || i == n || j == 1 || j == n;
if (isBorder)
cout << setw(3) << j;
else
cout << " ";
}
cout << "\n";
}
return 0;
} Uses a simple isBorder flag instead of side-specific counters — good starting point before adding clockwise numbering for arbitrary n.
Smaller 3×3 grid for quick tracing on paper or in interviews.
Use n = 3 with scaled counter starts — trace all four sides before scaling to 5×5.
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
int n = 3;
int i, j;
int k = n + 1, l = 3 * n - 2, m = 4 * (n - 1);
for (i = 1; i <= n; i++) {
for (j = 1; j <= n; j++) {
if (i == 1)
cout << setw(3) << j;
else if (j == n)
cout << setw(3) << k++;
else if (i == n)
cout << setw(3) << l--;
else if (j == 1)
cout << setw(3) << m--;
else
cout << " ";
}
cout << "\n";
}
return 0;
} With only nine cells and one inner gap, you can trace every border branch on paper before running the full 5×5 demo.
k = 6, l = 13, m = 16 — starting values for right, bottom, and left borders.
for (i = 1; i <= 5; i++) for (j = 1; j <= 5; j++) — visit every cell.
if (i==1) top, else if (j==5) right, else if (i==5) bottom, else if (j==1) left — else inner space.
cout << setw(3) << value for border digits, " " for inner cells — then cout << "\n".
25 cells visited — O(n²) time, O(1) extra memory.
Trace which branch runs for representative cells in the 5×5 grid.
(i, j) | Branch | Prints | Notes |
|---|---|---|---|
(1, 3) | i == 1 | 3 | Top row uses column index |
(2, 5) | j == 5 | 6 | First right-column value (k++) |
(3, 3) | else (inner) | | Three spaces — hollow interior |
(4, 1) | j == 1 | 15 | Left column (m--) |
(5, 3) | i == 5 | 11 | Bottom row (l--) |
Check order matters: top row is tested first, then right column, then bottom, then left — corners belong to the first matching branch.
Where this tiny pattern (and its loop structure) shows up beyond the homework prompt.
Nested i, j loops with per-cell decisions — foundation for matrix problems.
Example: trace cell (3,3) in the walkthrough — inner branch prints spaces.
setw(3) keeps columns aligned when border numbers have 1 or 2 digits.
Example: compare output with and without formatting — columns drift without width 3.
Separate k, l, m track different sides — state management in a small program.
Example: right column starts at 6 and increments through row 4.
Hollow patterns print only on the boundary — compare with filled square variants.
Example: replace inner spaces with * to fill the square.
Every cell visited once — makes O(n²) concrete for n×n grids.
Example: 5×5 = 25 cell checks — see the walkthrough table.
Pair the pattern with cin >> n return checks and minimum-size validation.
Example: reject n < 2 in Example 2.
Pro Tip: in grid patterns, consistent spacing matters as much as the numbers — use fixed-width formatting from the start.
Why this pattern earns a permanent spot in beginner C courses.
The hollow border is instantly recognizable — numbers ring the square while the interior stays blank.
Fixed-width setw(3) formatting teaches real console grid alignment — not abstract loop drill.
Fill the interior with * for a solid square, or scale counter formulas for larger grids.
Streaming output needs no storage beyond loop counters.
Pro Tip: trace the 3×3 compact example on paper — only one inner cell to mark as spaces.
Small habits that keep number-pattern code clean.
Print the digit when i == j; otherwise print a single space.
Avoid using uninitialized n when the user types letters instead of a number.
Only call cout << "\n" after the inner loop finishes each row.
Use for (k = 2; k <= rows; k++) so the center position is not duplicated.
Trace five rows on paper before coding the full 10-row demo.
Pro Tip: if the output is a vertical list of single numbers, you almost certainly put cout << "\n" inside the inner loop.
Mistakes that commonly break hollow square border number pattern patterns.
Each number lands on its own line — you get a column, not a square row.
→ Use cout << setw(3) << j or cout << " "; call cout << "\n" only after the inner loop.
Starting at k = 1 can print a third digit at the center — row looks crowded.
→ Use for (k = 2; k <= rows; k++) — mirror from column 2 onward.
Using j == rows instead of i == j places digits on the wrong diagonal.
→ Always compare the outer row index i with the inner loop variable j or k.
All numbers print on one long line without row breaks.
→ Add cout << "\n" after both inner loops complete.
Letters or empty input leave n uninitialized or wrong.
→ Check cin.fail() after cin >> n and re-prompt on failure.
Check these inputs before calling the solution done.
Output is a single cell — for n = 1 every position is border; validate n >= 2 in user input.
Outer loop never runs — print nothing or show a message.
rows < 0Treat as invalid; re-prompt instead of silent empty output.
Center cell (3,3) is the only inner cell — good for tracing the else branch.
Unchecked cin >> n fails silently — check the return value.
Row 9 scans 17 character positions (2×9-1) — total work grows as O(n²).
Try these variations to lock in the pattern.
" " with a digit or *i == 1. Right: j == n. Bottom: i == n. Left: j == 1. Else: three spaces.cout stays on the line; cout << "\n" advances — call it only after the inner loop finishes each row.n >= 2 for interactive programs; n = 2 has no inner cells — all border.O(n²) for square size n.Quick Takeaway: nested i, j loops, border if chain, counters k, l, m, width 3, then cout << "\n".
| Program | Time | Extra space |
|---|---|---|
| Nested loops (Examples 1–3) | O(n²) | O(1) |
| Digits on row i | 2i - 1 | No storage beyond loop counters |
The hollow square border number pattern is a natural follow-up to Program 58: rectangular grids with border detection and fixed-width formatting replace diagonal mirror loops. Master the fixed 5×5 version, then try user input and the compact 3×3 trace.
Practice the three examples above, then continue to Program 60 for the next pattern in the series.
Border shows numbers 1–16 clockwise on a 5×5 grid — inner cells stay blank with width-3 spacing.
for (j = rows; j >= 1; j--) with if (i == j)for (k = 2; k <= rows; k++) with if (i == k)cout << "\n" after the inner loopcin >> n with return-value checks for user inputk = 1 — can triple-print at centerj == rows instead of i == j — wrong diagonalcout << "\n" inside the inner looprows = 3 dry-run before coding rows = 5Print the hollow border square the beginner-friendly way.
border only
Definitionj = rows..1
Codek = 2..rows
Codei == j or i == k
LogicO(n²) time
AnalysisThis pattern is a hollow 5×5 border: top row 1..5, right side 6..9, bottom row 13..9, left side 16..13 — inner cells are blank spaces with fixed width 3.
Move on to the next pattern in the C++ number-pattern series.
12 people found this page helpful