JavaScript Mirrored Number Pattern (Spaced)

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

What Is This Pattern?

A mirrored number pattern prints left digits 1..i and right digits i..1 inside two fixed-width loops — spaces fill unused columns so both halves stay aligned.

Remember
Rule: for i = 1..rows
      left  = j if j <= i else space   (j = 1..rows)
      right = space if k > i else k   (k = rows..1)

1        1
12      21
123    321
1234  4321
1234554321     ← rows = 5

Unlike Program 27’s tight palindrome, this version keeps a shrinking gap — a natural step after the 0-centered mirror in Program 28.

How to Solve It

Walk i from 1 to rows; fill a left half of width rows, then a right half of width rows.

MethodIdeaBest for
Two fixed loopsLeft digits/spaces + right spaces/digitsLearning, interviews
prompt rowsSame loops; ternary conditionsInteractive practice
Compact rows = 3Same structure; easier to trace by handPaper walkthrough

Pseudocode

Pseudocode
for i from 1 to rows:
    line = ""
    for j from 1 to rows:
        line += j if j <= i else " "
    for k from rows down to 1:
        line += " " if k > i else k
    print line (with newline)

Cheat sheet

GoalPattern
Set rowsconst rows = 5;
Outer loopfor (let i = 1; i <= rows; i++)
Left halfif (j <= i) line += j; else line += " ";
Right halfif (k > i) line += " "; else line += k;
End rowconsole.log(line);
Ternary formline += (j <= i) ? j : " ";
User inputconst rows = parseInt(prompt(...), 10);

Printing Numbers vs Starting a New Line

APIEffectUse for
line += j / line += " "Stays on the same rowEach digit or space
console.log(line)Ends the lineAfter both halves

Build the full row with +=, then break once with console.log. Putting console.log inside an inner loop prints one character per line.

Live Preview

Change the row count and the spaced mirror updates instantly.

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

Live result rows = 5 · width = 10
1        1
12      21
123    321
1234  4321
1234554321

Worked Walkthrough — rows = 3

Trace each outer i, the left half, the right half, and the printed row.

iLeft j=1..3Right k=3..1Printed row
11 + 2 spaces2 spaces + 11 1
212 + 1 space1 space + 2112 21
3123321123321

Gap spaces between digit groups = 2 * (rows - i) — zero when i = rows.

JavaScript Programs

Three complete programs: fixed rows = 5, prompt rows, and compact rows = 3. Use View Output for sample results, or Try It Yourself to edit and run in the playground.

Example 1 — Fixed rows = 5

Hard-coded row count — left loop j = 1..5, right loop k = 5..1, with if/else for digits vs spaces.

JavaScript
const rows = 5;

for (let i = 1; i <= rows; i++) {
  let line = "";
  for (let j = 1; j <= rows; j++) {
    if (j <= i) {
      line += j;
    } else {
      line += " ";
    }
  }
  for (let k = rows; k >= 1; k--) {
    if (k > i) {
      line += " ";
    } else {
      line += k;
    }
  }
  console.log(line);
}
Try It Yourself

How It Works

1. Outer loop. i runs from 1 to 5 — how many digit columns are active on each side.

2. Left half. For j = 1..5, append j when j <= i, else a space.

3. Right half. For k = 5..1, append a space when k > i, else append k; then console.log(line).

Example 2 — prompt Rows

Read the row count at runtime; use ternary conditions in both inner loops.

JavaScript
const rows = parseInt(prompt("Enter rows:"), 10);

if (!Number.isFinite(rows) || rows < 1) {
  console.log("Please enter a positive integer.");
} else {
  for (let i = 1; i <= rows; i++) {
    let line = "";
    for (let j = 1; j <= rows; j++) {
      line += (j <= i) ? j : " ";
    }
    for (let k = rows; k >= 1; k--) {
      line += (k > i) ? " " : k;
    }
    console.log(line);
  }
}
Try It Yourself

How It Works

1. Prompt and validate. Parse the answer; reject non-positive or non-numeric input.

2. Same shape. Both inner loops still run rows times — only the bound changes.

3. Ternaries. (j <= i) ? j : " " and (k > i) ? " " : k replace if/else.

Example 3 — Compact rows = 3

Same if/else structure with a smaller row count — easy to trace on paper.

JavaScript
const rows = 3;

for (let i = 1; i <= rows; i++) {
  let line = "";
  for (let j = 1; j <= rows; j++) {
    if (j <= i) {
      line += j;
    } else {
      line += " ";
    }
  }
  for (let k = rows; k >= 1; k--) {
    if (k > i) {
      line += " ";
    } else {
      line += k;
    }
  }
  console.log(line);
}
Try It Yourself

How It Works

1. Same structure. Outer and both inner loops match Example 1.

2. Only rows changes. Width is 3 per half — final row is 123321 with no gap.

3. Trace first. Walk i = 1, 2, 3 on paper before scaling to 5 or more.

Edge Cases & Pitfalls

Check these before calling the solution done.

no spaces

Missing filler spaces

Printing only digits collapses the gap — the right half slides left and the mirror no longer looks centered.

wrong bound

Inner loop to i only

Both loops must run to rows, not i. Stopping early removes the alignment spaces.

log inside

Vertical output

If console.log is inside either inner loop, each character lands on its own line. Log only after both halves.

rows = 1

Smallest mirror

Output is 11 — left prints 1, right prints 1, no gap.

flip test

Swapped conditions

Using j > i for digits on the left (or k <= i for spaces on the right) breaks the shape.

NaN input

Validate parseInt

Letters or empty prompt yield NaN — check Number.isFinite(rows) && rows >= 1.

Time and Space Complexity

ProgramTimeExtra space
Examples 1–3O(n²)O(n) for the current line string

n rows, each with two loops of width n → O(n²).

Key Takeaways

  • Rule: left 1..i (pad spaces), right i..1 (pad spaces).
  • Fixed width: both inner loops always run rows times.
  • Write vs log: line += … builds; console.log(line) breaks.
  • Complexity: O(n²) for n rows.

One line: grow digits from both sides while spaces shrink the middle gap until the last row joins.

Frequently Asked Questions

Spaces keep the left and right halves aligned so the pattern looks symmetric. Without them, the right half shifts left each row.
The right loop runs k from rows down to 1. When k > i it appends a space; otherwise it appends k — building i..1 on the right.
Both inner loops always run rows times. Extra positions are filled with spaces so columns stay aligned.
Program 27 prints a tight palindrome with no alignment spaces. Program 29 uses fixed-width loops and spaces for a symmetric spaced mirror.
When i equals rows, both halves fill all columns — 12345 on the left and 54321 on the right meet with no space between.
Replace 5 with rows in both inner loop bounds — see Example 2.
O(n²) for n rows because each row runs two inner loops of width n.
Use parseInt with Number.isFinite so bad input does not produce NaN.
Yes — line += (j <= i) ? j : " " compacts the if/else logic in JavaScript.

Did you know?

This pattern prints an increasing left half (1..i), then a mirrored right half (i..1). Spaces in the fixed-width loops keep both halves aligned until the final row joins without a gap.

Next: Right-Aligned Descending Triangle

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

Program 30 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