Shape Rule
Left + right mirror
Left half grows 1..i; right half mirrors i..1 with spaces keeping alignment.

The mirrored number pattern prints 1 1, 12 21, 123 321, 1234 4321, 1234554321 — a natural step after the 0-centered mirror in Program 28. This tutorial covers fixed-width loops, space alignment, conditional printing, a live preview, worked JavaScript examples, edge cases, and complexity.
Left + right mirror
Left half grows 1..i; right half mirrors i..1 with spaces keeping alignment.
i = 1..rows
for (let i = 1; i <= rows; i++) — one mirrored row per iteration.
1..rows
if j <= i prints digit; else prints a space.
rows..1
if k > i prints space; else prints k.
3–9 rows
Pick a row count and draw the spaced mirror pattern in the browser.
Complexity
Each row runs two loops of width rows — total work scales as n².
A mirrored number pattern prints an increasing left half (1..i) and a decreasing right half (i..1) on the same row. With rows = 5, spaces keep both halves aligned until the final row joins as 1234554321.
In JavaScript you use fixed-width inner loops: left loop prints digits or spaces with j <= i, right loop mirrors with k > i for spaces.
It combines conditional printing with space alignment — a step up from Program 28’s digit-only mirror.
Both inner loops always run rows times.
Print digit or space on the left half.
Print space or digit on the right half.
Follow Program 28; continue to Program 30 (right-aligned triangle) next.
In short: for each i, left loop appends j or space, right loop appends k or space, then console.log(line).
Given rows = 5, print a mirrored pattern: for each i, print digits or spaces in a fixed-width left loop, then digits or spaces in a fixed-width right loop.
// rows = 5 (conceptual shape)
// 1 1
// 12 21
// 123 321
// 1234 4321
// 1234554321 | Item | Type | Description |
|---|---|---|
rows | int | Pattern height — also the fixed width of both inner loops. |
i | int | Outer loop — current row; controls how many digits print on each side. |
j | int | Left loop — prints j when j <= i, else a space. |
k | int | Right loop — prints k when k <= i, else a space. |
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
console.log(line) | Approach | Idea | Best for |
|---|---|---|
| if/else per loop | 1 1, 12 21, … | Learning and interviews |
| Ternary operator | line += (j <= i) ? j : " " | Compact console programs |
| User-input rows | const rows = parseInt(prompt(...), 10) | Flexible row count |
| Goal | Pattern |
|---|---|
| Walk rows | for (let i = 1; i <= rows; i++) |
| Left half | if (j <= i) { line += j; } else { line += " "; } |
| Right half | if (k > i) { line += " "; } else { line += k; } |
| End the row | console.log(line) |
| Conditional form | line += (j <= i) ? j : " " |
| User input | const rows = parseInt(prompt(...), 10) |
Same spaced mirror — different ways to write the conditions and control rows.
i = 1..rowsOne mirrored row per iteration
j if j <= i else " "Digit or space
" " if k > i else kSpace or digit
2 x rowsBoth loops always width rows
Reach for this pattern when teaching fixed-width loops, space alignment, and conditional character output.
Natural follow-up after Program 28 — introduces space padding for symmetric alignment.
Outer/inner bound practice with an immediate visual check.
Combine loops with prompt() for a flexible row count.
Compare Program 28 (0-centered mirror) and Program 30 (right-aligned triangle) next.
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 row count between 3 and 9 and draw the spaced mirror pattern in the browser.
Three complete JavaScript programs — fixed rows, user input with conditional expression form, and a smaller trace demo. Click View Output to reveal sample console results, or Try it Yourself to run the code live.
Print five rows of the spaced mirror with if/else in both inner loops.
rows = 5Hard-coded row count — ideal for first demos and screenshots.
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);
} When i = 1, the left loop prints 1 and four spaces; the right prints four spaces then 1 — output 1 1. When i = 5, both halves fill all columns — output 1234554321 with no gap.
Read the row count with prompt() instead of hard-coding 5.
Read rows with prompt() and parseInt(); both inner loops use rows as the width.
const rowsInput = prompt("Enter rows:");
const rows = parseInt(rowsInput, 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);
}
} Same spaced-mirror core as Example 1; conditional expressions replace if/else and rows replaces hard-coded 5. Non-numeric input yields NaN with bare parseInt(prompt(), 10) — validate with Number.isFinite for safer labs.
Run with rows = 3 to trace every row on paper before scaling up.
rows = 3Same if/else logic with a smaller row count for quick tracing.
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);
} Only rows changes from 5 to 3 — the if/else structure stays identical. Trace i = 1, 2, 3 on paper to see how spaces shrink each row.
console.log is built in; use prompt() when reading input. Set loop variables i, j, k with rows = 5.
for (let i = 1; i <= rows; i++) — ascending outer loop; one mirrored row per iteration.
for (let j = 1; j <= rows; j++) — append j if j <= i, else a space.
for (let k = rows; k >= 1; k--) — append space if k > i, else k.
console.log(line) ends the row after both inner loops finish.
Spaces shrink each row until the final join — O(n²) time, O(1) extra memory.
rows = 5Trace each outer-loop value of i, what the left and right loops print, and the full row output.
i | Left (j) | Right (k) | Row output |
|---|---|---|---|
1 | 1, space, space, space, space | space, space, space, space, 1 | 1 1 |
2 | 1, 2, space, space, space | space, space, space, 2, 1 | 12 21 |
3 | 1, 2, 3, space, space | space, space, 3, 2, 1 | 123 321 |
4 | 1, 2, 3, 4, space | space, 4, 3, 2, 1 | 1234 4321 |
5 | 1, 2, 3, 4, 5 | 5, 4, 3, 2, 1 | 1234554321 |
Gap spaces = 2 * (rows - i) between the left and right digit groups — zero when i = rows.
Where this tiny pattern (and its loop structure) shows up beyond the homework prompt.
Clearest visual proof that outer and inner bounds interact.
Example: flip j <= i to j > i for digits and watch alignment break.
Foundation for inverted, pyramid, diamond, and hollow variants.
Example: continue to Program 30 for a right-aligned descending triangle.
Practice line += vs console.log(line) without complex math.
Example: put console.log(line) inside an inner loop by mistake.
Add spaces between digits once the two-loop structure works.
Example: use line += j + " " in both inner loops.
Triangular totals make O(n²) concrete for beginners.
Example: count printed characters for rows = 5 — each row prints 2 * rows characters.
Pair the pattern with Number.isFinite and positive-row checks.
Example: reject rows <= 0 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, and k on paper for rows = 3 before coding — watch how gap spaces shrink each row.
Small habits that keep number-pattern code clean.
Both inner loops must use rows as the bound — mismatched widths break alignment.
prompt()Validate parseInt(prompt(), 10) with Number.isFinite so bad input does not produce NaN.
console.log(line) OutsideOnly call console.log(line) after both inner loops finish the row.
Mark the ascending half and mirror half for each row before coding.
Trace i = 1..3 on paper before coding the full rows = 5 demo.
Pro Tip: if the output is a vertical list of single digits per line, you almost certainly put console.log(line) inside an inner loop.
Mistakes that commonly break spaced mirror patterns.
Each digit lands on its own line — you get a column, not a triangle.
→ Use line += j, line += " ", or line += k; console.log(line) only after both inner loops.
Using k <= i for spaces on the right (instead of k > i) inverts the mirror half.
→ Left: print digit when j <= i. Right: print space when k > i.
Printing only digits without padding collapses the symmetric shape into a tight palindrome.
→ Use line += " " in the else branches to maintain fixed width.
Left loop to i but right loop to rows - 1 misaligns columns.
→ Both inner loops must run exactly rows iterations.
Letters or empty input yield NaN from parseInt(prompt(), 10).
→ Validate with Number.isFinite and re-prompt on failure.
Check these inputs before calling the solution done.
Output is 11 — both halves print one digit with no gap.
Outer loop never runs — print nothing or show a message.
rows < 0Treat as invalid; re-prompt instead of silent empty output.
Two rows: 1 1 and 1221.
parseInt(prompt(), 10) yields NaN — validate with Number.isFinite first.
Each row prints 2 * rows characters — grows as rows² total work.
Try these variations to lock in the pattern.
" " with "." or "*"j <= i, space otherwise. Right loop: space when k > i, digit otherwise.line += builds the row; console.log(line) ends it — keep them in the right order.rows > 0 for interactive programs; rows = 1 prints 11.rows times — fixed width is what creates the alignment.Quick Takeaway: outer loop i = 1..rows, left j if j <= i else " ", right " " if k > i else k, 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 mirrored number pattern is a compact lesson in fixed-width loops and space alignment: append digits or spaces on the left with j <= i, mirror on the right with k > i, and end each row with console.log(line). Master the fixed-rows version, then try user input and a smaller trace demo.
Practice the three examples above, then continue to Program 30 for the right-aligned descending number triangle.
Both inner loops must use rows as the width — validate rows when reading from the console.
for (let i = 1; i <= rows; i++) in the outer loopif j <= i print digit, else print spaceif k > i print space, else print krowsparseInt(prompt(), 10) with Number.isFinite before using rowsconsole.log(line) inside either inner looprows = 1 edge casePrint the pattern the beginner-friendly way.
j<=i, k>i spaces
Definition2 x rows
CodeDigit or space
CodeSpace or digit
ShapeO(n²) time
AnalysisThis 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.
Move on to the right-aligned descending number triangle in the JavaScript number-pattern series.
12 people found this page helpful