Shape Rule
Border only
Print 1 on the first/last row and first/last column — leave interior cells as spaces.

The hollow square of 1s prints a 5×5 border frame — 1 1 1 1 1 on top and bottom, 1 on the sides, spaces inside — a natural step after Program 41’s square pyramid. This tutorial covers nested loops, border conditions, a live preview, worked JavaScript examples, edge cases, and complexity.
Border only
Print 1 on the first/last row and first/last column — leave interior cells as spaces.
Rows (i)
for (let i = 1; i <= n; i++) walks each row of the grid.
Columns (j)
for (let j = 1; j <= n; j++) visits every column in the current row.
if condition
i === 1 || i === n || j === 1 || j === n — append "1 " on the edge, two spaces inside.
3–9 size
Pick a square size and draw the hollow border in the browser.
Complexity
Every cell in an n×n grid is visited once — total checks = n².
A hollow square of 1s prints 1 only on the border of an n×n grid and spaces everywhere else. With n = 5, the output is a 5×5 frame of ones with a hollow center.
In JavaScript nested loops walk every cell (i, j), an if checks whether the cell is on the border, and line += builds each row before console.log(line).
It combines nested loops with a boundary condition — a key step after Program 41’s formatted pyramid.
First/last row or column prints 1.
Nested loops visit every (i, j) cell.
Program 41 prints perfect squares; Program 42 prints a hollow frame.
Follow Program 41; continue to Program 43 (right-aligned triangle) next.
In short: for each (i, j) in an n×n grid, append 1 on the border else two spaces, then console.log(line) each row.
Given a grid size n (e.g. 5), print a hollow square border of 1s using nested loops and a border condition.
// n = 5 (conceptual shape)
// 1 1 1 1 1
// 1 1
// 1 1
// 1 1
// 1 1 1 1 1 | Item | Type | Description |
|---|---|---|
n | number | Side length of the square grid — both loops run 1..n. |
i | number | Outer loop — row index from 1 to n. |
j | number | Inner loop — column index from 1 to n. |
for i from 1 to n:
for j from 1 to n:
if i is border or j is border:
print 1
else:
print space
print newline | Approach | Idea | Best for |
|---|---|---|
| Border condition | 1 1 1 1 1 frame | Learning and interviews |
| User-input size | parseInt(prompt(), 10) | Flexible console programs |
| Custom border char | Print * instead of 1 | Visual variety |
| Goal | Pattern |
|---|---|
| Walk rows | for (let i = 1; i <= n; i++) |
| Walk columns | for (let j = 1; j <= n; j++) |
| Border check | if (i === 1 || i === n || j === 1 || j === n) |
| Append border | line += "1 " |
| Append interior | line += " " |
| End the row | console.log(line) |
| Program 41 contrast | Perfect-square pyramid — not a hollow grid |
Same hollow square — different ways to control size and border character.
i = 1..nRow index
j = 1..nColumn index
i/j === 1 || nEdge cells append 1
line +=Keeps grid aligned
Reach for this pattern when teaching boundary conditions with nested loops on a 2D grid.
Natural follow-up — boundary conditions on a grid instead of formatted square pyramids.
Outer/inner bound practice with an immediate visual check.
Combine loops with prompt() for a flexible square size.
Swap 1 for * on the border — see Example 3.
This is a console teaching pattern — not how you build modern app screens.
Key benefit: one small program that locks in nested loops, output sequencing, and O(n²) thinking.
Choose a square size between 3 and 9 and draw the hollow border in the browser.
Three complete JavaScript programs — fixed size, prompt() input, and asterisk border. Click View Output to reveal sample console results, or Try it Yourself to run the code live.
Print a 5×5 hollow square border with nested loops and a border condition.
n = 5Hard-coded grid size — ideal for first demos and screenshots.
const n = 5;
for (let i = 1; i <= n; i++) {
let line = "";
for (let j = 1; j <= n; j++) {
if (i === 1 || i === n || j === 1 || j === n) {
line += "1 ";
} else {
line += " ";
}
}
console.log(line);
} When i = 1 or i = 5, every cell is on the border — all 1s. When i = 3 and j = 3, neither row nor column is on the edge — prints spaces.
Read the square size with prompt() instead of hard-coding 5.
Read n with prompt() and validate n ≥ 2 (check with Number.isFinite in real apps).
const nInput = prompt("Enter the size (n >= 2):");
const n = parseInt(nInput, 10);
if (!Number.isFinite(n) || n < 2) {
console.log("Please enter an integer n >= 2.");
} else {
for (let i = 1; i <= n; i++) {
let line = "";
for (let j = 1; j <= n; j++) {
if (i === 1 || i === n || j === 1 || j === n) {
line += "1 ";
} else {
line += " ";
}
}
console.log(line);
}
} Same border-check core as Example 1; only the source of n changes from a literal to user input. Non-numeric input yields NaN with bare parseInt() — use Number.isFinite for safer labs.
Swap 1 for * on the border — same condition, different character.
Keep n = 5 but print * on the border instead of 1.
const n = 5;
for (let i = 1; i <= n; i++) {
let line = "";
for (let j = 1; j <= n; j++) {
if (i === 1 || i === n || j === 1 || j === n) {
line += "* ";
} else {
line += " ";
}
}
console.log(line);
} Only the appended character changes — "* " instead of "1 " in the if branch. Loop bounds and border check stay the same as Example 1.
No imports needed. Set n = 5 and loop variables i, j.
for (let i = 1; i <= n; i++) — walks each row of the grid.
for (let j = 1; j <= n; j++) — visits every column in the current row.
if (i === 1 || i === n || j === 1 || j === n) — append "1 " on the edge, two spaces inside.
console.log(line) ends the row after the inner loop finishes.
Every cell in an n×n grid is visited — O(n²) time, O(1) extra memory.
n = 5, row i = 3Trace row 3 cell by cell — which cells print 1 and which print spaces.
j | On border? | Prints |
|---|---|---|
1 | Yes (j == 1) | 1 |
2 | No | |
3 | No | |
4 | No | |
5 | Yes (j == n) | 1 |
Border cells per row = 4n - 4 for n ≥ 2 — total grid visits = n².
Where this tiny pattern (and its loop structure) shows up beyond the homework prompt.
Clearest visual proof that outer and inner bounds interact.
Example: swap 1 for * on the border — see Example 3.
Foundation for inverted, pyramid, diamond, and hollow variants.
Example: continue to Program 43 for a right-aligned number triangle.
Practice line += vs console.log(line) without complex math.
Example: put console.log(line) inside the inner loop by mistake.
Use separate rows and cols with the same border check.
Example: change both loop bounds and border conditions.
Triangular totals make O(n²) concrete for beginners.
Example: count border cells for n = 5 — total is 16 (4n - 4).
Pair the pattern with Number.isFinite and prompt() validation.
Example: reject n < 2 and re-prompt.
Pro Tip: when an interviewer asks for patterns, explain the outer/inner roles first — then write the loops. The story matters as much as the code.
Why this pattern earns a permanent spot in beginner JavaScript courses.
Wrong bounds show up immediately as a broken staircase.
Only loops and console output — no arrays or math libraries.
Invert, center, hollow, or change the fill character with small edits.
Streaming output needs no storage beyond loop counters.
Pro Tip: trace (i, j) on paper for n = 3 before coding the full n = 5 demo.
Small habits that keep number-pattern code clean.
Border cells use line += "1 "; interior uses line += " " — same width keeps columns aligned.
Number.isFiniteUse Number.isFinite(n) so bad prompt() input does not crash when converting n.
console.log Outside the Inner LoopOnly call console.log(line) after the inner loop finishes the row.
i === 1 || i === n || j === 1 || j === n covers all four edges in one test.
Trace i = 1, 2, 3 and mark border cells before coding the full n = 5 demo.
Pro Tip: if the output is a vertical list of single digits per line, you almost certainly put console.log(line) inside the inner loop.
Mistakes that commonly break hollow square border patterns.
Each cell lands on its own line — you get a column, not a square.
→ Use line += "1 " or line += " " per cell; console.log(line) only after the inner loop.
Using i == 5 in the check breaks when n changes to 7 or 10.
→ Always use the n variable: i === n || j === n.
Border prints "1 " but interior prints a single space — columns drift apart.
→ Use two spaces for interior: line += " " to match "1 " width.
n = 1 prints a single 1 with no hollow interior; n = 2 is the thinnest frame.
→ Validate n ≥ 2 for interactive programs expecting a hollow square.
parseInt(prompt())Letters or empty input yield NaN with bare parseInt(prompt()).
→ Check Number.isFinite(n) and re-prompt on failure.
Check these inputs before calling the solution done.
Output is just 1 on one line — no hollow interior.
Outer loop never runs — print nothing or show a message.
n < 0Treat as invalid; re-prompt instead of silent empty output.
Thinnest hollow frame — four border cells forming a square ring.
Bare parseInt(prompt()) yields NaN on bad input — use Number.isFinite first.
Each cell visited once — total work grows as n² for an n × n grid.
Try these variations to lock in the pattern.
m*m pyramid1 in every cell — no border checkelse branch"*" instead of "1""1 " when i === 1 || i === n || j === 1 || j === n; else append " ".line +=, then console.log(line) once per row.n ≥ 2 for interactive programs; n = 1 should print a single 1.n × n grid has n² cells — border cells = 4*n - 4 for n ≥ 2.Quick Takeaway: nested loops over i, j, border check appends "1 ", else " ", then console.log(line).
| Program | Time | Extra space |
|---|---|---|
| Nested loops (Examples 1–3) | O(n²) | O(1) |
| Smaller demo (Example 3) | O(n²) | O(1) |
The hollow square border is a compact nested-loop lesson: visit every cell in an n × n grid and use a border condition to print 1 or spaces. Master the fixed-n version, then try user input and a custom border character.
Practice the three examples above, then continue to Program 43 for the next pattern in the series.
Border = first/last row or column — keep cell width consistent ("1 " vs " ") and validate n when reading input.
for (let i = 1; i <= n; i++) and for (let j = 1; j <= n; j++)if (i === 1 || i === n || j === 1 || j === n)"1 " on border, " " inside — same cell widthn ≥ 2 for interactive programsNumber.isFinite(n) after parseInt(prompt())console.log(line) inside the inner cell loop5 in the border conditionn = 1 edge casePrint the pattern the beginner-friendly way.
Border cells only
DefinitionRows i = 1..n
CodeColumns j = 1..n
Codei/j on edge
LogicO(n²) time
AnalysisAppend 1 when i === 1, i === n, j === 1, or j === n; otherwise append two spaces. A n × n grid visits n² cells — total appends = n².
Move on to the right-aligned number triangle in the JavaScript number-pattern series.
12 people found this page helpful