JavaScript Hollow Square Number Pattern (Border)

Beginner
5 min read
Updated: Sep 2026
3 programs
Live preview

What Is This Pattern?

A hollow square border number pattern prints consecutive numbers only on the boundary of an n×n grid — the interior stays blank.

Remember
Rule: numbers on border only (clockwise)

  1  2  3  4  5
 16           6
 15           7
 14           8
 13 12 11 10  9   ← n = 5

Unlike Program 58 (diagonal diamond), this uses a rectangular grid with side counters — border count = 4(n - 1).

How to Solve It

Visit every cell; branch by side (i === 1, j === n, i === n, j === 1); pad to width 3.

MethodIdeaBest for
Side countersTop uses j; right/bottom/left use k, l, mClassic clockwise demos
CompactSame logic with n = 3 and scaled startsQuick dry-runs

Pseudocode

Pseudocode
k = n + 1
l = 3*n - 2
m = 4*(n - 1)
for i from 1 to n:
    line = ""
    for j from 1 to n:
        if i === 1:      append padded j
        else if j === n: append padded k; k += 1
        else if i === n: append padded l; l -= 1
        else if j === 1: append padded m; m -= 1
        else:            append "   "
    print line

Cheat sheet

GoalPattern
Counter startsk = n+1, l = 3*n-2, m = 4*(n-1)
Top rowif (i === 1) line += String(j).padStart(3, " ");
Right columnelse if (j === n) { line += …k; k++; }
Bottom rowelse if (i === n) { line += …l; l--; }
Left columnelse if (j === 1) { line += …m; m--; }
Interiorelse line += " ";
End the rowconsole.log(line);

Printing Numbers vs Starting a New Line

APIEffectUse for
line += …Stays on the same rowEach padded cell
console.log(line)Ends the current rowAfter all columns finish

Append without a newline, then end the row once.

Live Preview

Change the size and the hollow border updates instantly.

Whole numbers from 2 to 9. Tap a chip or type a value — the preview redraws as you go.

Live result n = 5 · 16 border numbers
  1  2  3  4  5
 16           6
 15           7
 14           8
 13 12 11 10  9

Worked Walkthrough

Trace the four sides when n = 5 — each side owns its own counter.

SideConditionValues
Topi === 11 2 3 4 5
Rightj === 5 (rows 2..5)6 7 8 9
Bottomi === 5 (cols 1..4)13 12 11 10
Leftj === 1 (rows 2..4)16 15 14

Check sides in order: top → right → bottom → left. The bottom-right corner is claimed by the right branch (j === n).

JavaScript Programs

Three complete programs: fixed 5×5, prompt size with the same clockwise formula, and a compact 3×3 demo. Use View Output for samples, or Try It Yourself to edit and run live.

Example 1 — Fixed 5×5 Border

Hard-coded counters for n = 5: k = 6, l = 13, m = 16.

JavaScript
let k = 6;
let l = 13;
let m = 16;

for (let i = 1; i <= 5; i++) {
  let line = "";

  for (let j = 1; j <= 5; j++) {
    if (i === 1) {
      line += String(j).padStart(3, " ");
    } else if (j === 5) {
      line += String(k).padStart(3, " ");
      k++;
    } else if (i === 5) {
      line += String(l).padStart(3, " ");
      l--;
    } else if (j === 1) {
      line += String(m).padStart(3, " ");
      m--;
    } else {
      line += "   ";
    }
  }

  console.log(line);
}
Try It Yourself

How It Works

1. Top row uses column index. When i === 1, append padded j for every column.

2. Right, bottom, and left use counters. k++ down the right, l-- across the bottom, m-- up the left.

3. Interior stays blank. Non-border cells append three spaces so columns stay aligned with padStart(3).

Example 2 — User Input Size

Read n with prompt and scale the three counter starts from formulas.

JavaScript
const n = parseInt(prompt("Enter square size (n):"), 10);

if (!Number.isFinite(n) || n < 2) {
  console.log("Please enter an integer >= 2.");
} else {
  let k = n + 1;
  let l = 3 * n - 2;
  let m = 4 * (n - 1);

  for (let i = 1; i <= n; i++) {
    let line = "";

    for (let j = 1; j <= n; j++) {
      if (i === 1) {
        line += String(j).padStart(3, " ");
      } else if (j === n) {
        line += String(k).padStart(3, " ");
        k++;
      } else if (i === n) {
        line += String(l).padStart(3, " ");
        l--;
      } else if (j === 1) {
        line += String(m).padStart(3, " ");
        m--;
      } else {
        line += "   ";
      }
    }

    console.log(line);
  }
}
Try It Yourself

How It Works

1. Prompt and validate. Require n >= 2 so a hollow border can exist.

2. Scale the starts. k = n+1, l = 3n-2, m = 4(n-1) match Example 1 when n = 5.

3. Entering 4. Twelve border numbers (4×3), last corner is 7 on the bottom-right.

Example 3 — Compact 3×3 Border

Same side-counter logic with n = 3 for a quick visual check.

JavaScript
const n = 3;
let k = n + 1;
let l = 3 * n - 2;
let m = 4 * (n - 1);

for (let i = 1; i <= n; i++) {
  let line = "";

  for (let j = 1; j <= n; j++) {
    if (i === 1) {
      line += String(j).padStart(3, " ");
    } else if (j === n) {
      line += String(k).padStart(3, " ");
      k++;
    } else if (i === n) {
      line += String(l).padStart(3, " ");
      l--;
    } else if (j === 1) {
      line += String(m).padStart(3, " ");
      m--;
    } else {
      line += "   ";
    }
  }

  console.log(line);
}
Try It Yourself

How It Works

1. Shrink the size. Only n changes — counter formulas still drive all four sides.

2. Easier to trace. Eight border numbers — useful while learning side order.

3. Same padding rule. Width 3 keeps columns aligned even on a tiny grid.

Edge Cases & Pitfalls

Check these before calling the solution done.

Branch order

Test right (j === n) before bottom (i === n)

The bottom-right corner belongs to the right counter — swapping order breaks clockwise numbering.

Padding

Match interior spaces to padStart width

Use three spaces inside when border values use width 3.

n = 2

No interior cells

Every position is on the border — four numbers total.

Bad input

Validate parseInt

Check Number.isFinite(n) and require n >= 2 before the loops.

Time and Space Complexity

ProgramTimeExtra space
Fixed / compact (Examples 1, 3)O(n²)O(n) per row string
User input (Example 2)O(n²)O(n) per row string

Every cell of the n×n grid is visited once — quadratic time; only the current row string is stored.

Key Takeaways

  • Rule: print numbers only on the border — clockwise with side counters.
  • Align: padStart(3) for numbers, three spaces for the interior.
  • Break the row: call console.log(line) only after all columns finish.
  • Complexity: O(n²) — visit every cell once.

One line: walk the grid, fill the four borders clockwise with counters, leave the inside blank.

Frequently Asked Questions

A cell is on the border if i === 1, i === n, j === 1, or j === n — inner cells append three spaces.
Fixed width 3 keeps every column aligned when border numbers have one or two digits.
k tracks the right column, l the bottom row (descending), m the left column (descending).
line += appends a padded number or spaces on the same row. console.log ends the row after all columns finish.
Program 58 prints a diagonal mirror diamond. Program 59 prints a rectangular hollow border with side counters.
O(n²) for an n×n grid because every cell is visited once.
4(n - 1) for n >= 2 — for n = 5 that is 16 numbers.
A 2×2 grid has no inner cells — every position is on the border.

Did you know?

A hollow n×n border has 4(n-1) numbers. For n = 5: top 1..5, right 6..9, bottom 13..9, left 16..13 — inner cells are three spaces for alignment.

Next: Remove Last Digit Pattern

Continue with the next pattern in the JavaScript number-pattern series.

Program 60 tutorial →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

12 people found this page helpful