Diagonal Mirror Number Diamond in JavaScript

Beginner
⏱️ 10 min read
📚 Updated: Sep 2026
🎯 3 Code Examples
🚀 Live Preview
Nested Loops + Symmetry

What You’ll Learn

Program 58 prints a diagonal mirror number diamond: the top half grows from 1 to rows like Program 57, then a second outer loop mirrors back down to 1. This tutorial covers top/bottom halves, conditional diagonal printing, a live preview, worked JavaScript examples, edge cases, and complexity.

Shape Rule

Full diamond

Top half: row i prints digit i on mirror diagonals. Bottom half: same logic with i counting down.

Top Outer Loop

i = 1..rows

for (let i = 1; i <= rows; i++) — same pyramid half as Program 57.

Bottom Outer Loop

i = rows-1..1

for (let i = rows - 1; i >= 1; i--) — mirrors the top half without repeating the peak row.

Left Diagonal

j = rows..1

line += (i === j) ? i : " " — reused in both outer loops.

Right Diagonal

k = 2..rows

line += (i === k) ? i : " " — mirrors the left half from column 2 onward.

O(n²)

Complexity

2×rows-1 lines, each scanning about 2×rows-1 positions — total work grows as O(n²).

Introduction

A diagonal mirror number diamond extends Program 57’s pyramid: print the top half from 1 to rows, then mirror back down with a second outer loop from rows-1 to 1. With rows = 5, you get nine lines — peak at row 5, then symmetric descent to a single 1.

Each row reuses Program 57’s inner loops: left diagonal j = rows..1, right diagonal k = 2..rows, appending the digit only when i === j or i === k.

Why it matters?

It bridges Program 57’s single pyramid to full symmetry — one extra outer loop turns a half-pattern into a complete diamond.

Key Highlights

Top half

i = 1..rows — pyramid grows upward.

Bottom half

i = rows-1..1 — mirror without repeating peak.

vs Program 57

Program 57 is the top half only; Program 58 adds the mirrored bottom loop.

Series Foundation

Follow Program 57; continue to Program 59 next.

In short: top loop 1..rows, bottom loop rows-1..1, same inner diagonal logic per row, then console.log(line).

📝 Problem & Approach

Given row count rows = 5, print a diagonal mirror number diamond — top half 1..rows, bottom half rows-1..1, with mirror diagonals on every line.

JavaScript
// rows = 5
//     1
//    2 2
//   3   3
//  4     4
// 5       5
//  4     4
//   3   3
//    2 2
//     1

Inputs & Outputs

ItemTypeDescription
rowsintHalf-height — diamond has 2×rows-1 total lines.
i (top outer)intRuns 1 to rows — builds the upper half.
i (bottom outer)intRuns rows-1 down to 1 — mirrors without repeating peak.
j (left)intScans rows..1 — appends digit when i === j.
k (right)intScans 2..rows — prints digit when i == k.
Total linesintrows + (rows - 1) = 2×rows - 1.

Minimal workflow

Pseudocode
for i from 1 to rows:
    print row i with left and right diagonal logic
for i from rows - 1 down to 1:
    print row i with same inner loop logic

Approach comparison

ApproachIdeaBest for
Two outer loopsTop 1..rows, bottom rows-1..1Learning and interviews
Reuse inner logicSame j and k loops in both halvesDRY diamond patterns
User-input rowsprompt() + parseInt()Flexible diamond size
Compact tracerows = 3 on paper firstQuick dry-runs before full demo
Character swapReplace digit with * for an X-diamondVisual debugging

⚡ Quick Reference

GoalPattern
Top outer loopfor (let i = 1; i <= rows; i++)
Bottom outer loopfor (let i = rows - 1; i >= 1; i--)
Left diagonalfor (let j = rows; j >= 1; j--) line += (i === j) ? i : " "
Right diagonalfor (let k = 2; k <= rows; k++) line += (i === k) ? i : " "
End rowconsole.log(line)
Program 57 contrastProgram 57 is top half only; Program 58 adds bottom mirror loop

📋 Fixed Rows vs User Input vs Compact Trace

Same diagonal mirror diamond — three ways to set row count and trace the logic.

Fixed rows
rows = 5

Hard-coded half-height for demos

User input
parseInt(prompt())

Read row count from console

Compact trace
rows = 3

5-line diamond dry-run

Top half
i = 1..rows

Program 57 pyramid logic

Bottom half
i = rows-1..1

Mirror without peak repeat

Context

When This Pattern Shows Up

Reach for this pattern when teaching symmetry, mirroring loops, and extending a half-pattern into a full diamond.

  1. Post Program 57 exercise

    Natural follow-up after Program 57’s pyramid — one extra outer loop completes the diamond.

  2. Symmetry drills

    Top and bottom halves share inner logic — good bridge to palindrome and mirror problems.

  3. Two outer loops

    Separate top and bottom boundaries — concrete loop-boundary practice.

  4. Gateway to Program 59

    Compare this hollow diamond with the next pattern in the series.

  5. Not a UI layout tool

    This is a console teaching pattern — not how you build modern app screens.

Key benefit: one small extension that locks in mirroring, symmetry, and O(n²) thinking.

🔮 Live Preview

Choose row count between 3 and 9 and draw the centered diagonal mirror number diamond in the browser.

Try 4, 5, or 7. Max up to 9 in this preview.

Live result
Press "Draw pattern".

Examples Gallery

Three complete JavaScript programs — fixed rows, user input, and a compact trace demo. Click View Output to reveal sample console results, or Try it Yourself to run in the browser.

📚 Getting Started

Print a full diagonal mirror diamond with half-height five — top loop 1..rows, bottom loop rows-1..1.

Example 1 — Fixed rows = 5

Hard-coded half-height — log the top pyramid, then mirror with a second outer loop using the same inner diagonal logic.

JavaScript
const rows = 5;

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

  for (let j = rows; j >= 1; j--) {
    line += (i === j) ? i : " ";
  }

  for (let k = 2; k <= rows; k++) {
    line += (i === k) ? i : " ";
  }

  console.log(line);
}

for (let i = rows - 1; i >= 1; i--) {
  let line = "";

  for (let j = rows; j >= 1; j--) {
    line += (i === j) ? i : " ";
  }

  for (let k = 2; k <= rows; k++) {
    line += (i === k) ? i : " ";
  }

  console.log(line);
}
Try it Yourself

How It Works

The first outer loop prints rows 1 through 5 (Program 57 logic). The second outer loop prints rows 4 down to 1 — reusing the same inner loops so the bottom half mirrors the top without repeating row 5.

📈 User Input

Read half-height with prompt() and Number.isFinite validation.

Example 2 — User Input Rows

Read rows with prompt() and validate the result.

JavaScript
const rowsInput = prompt("Enter the number of 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 = rows; j >= 1; j--) {
      line += (i === j) ? i : " ";
    }

    for (let k = 2; k <= rows; k++) {
      line += (i === k) ? i : " ";
    }

    console.log(line);
  }

  for (let i = rows - 1; i >= 1; i--) {
    let line = "";

    for (let j = rows; j >= 1; j--) {
      line += (i === j) ? i : " ";
    }

    for (let k = 2; k <= rows; k++) {
      line += (i === k) ? i : " ";
    }

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

How It Works

Same top-and-bottom outer loops as Example 1; only the source of rows changes from a literal to user input.

⚡ Compact Trace

Smaller half-height for quick tracing on paper or in interviews.

Example 3 — Compact rows = 3

Use rows = 3 for a 5-line diamond — trace both outer loops before scaling to 5.

JavaScript
const rows = 3;

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

  for (let j = rows; j >= 1; j--) {
    line += (i === j) ? i : " ";
  }

  for (let k = 2; k <= rows; k++) {
    line += (i === k) ? i : " ";
  }

  console.log(line);
}

for (let i = rows - 1; i >= 1; i--) {
  let line = "";

  for (let j = rows; j >= 1; j--) {
    line += (i === j) ? i : " ";
  }

  for (let k = 2; k <= rows; k++) {
    line += (i === k) ? i : " ";
  }

  console.log(line);
}
Try it Yourself

How It Works

With half-height 3 you get 5 total lines — enough to trace top loop, peak row, and bottom mirror on paper before the full demo.

🧠 How the Algorithm Prints Rows

1

Set rows

rows = 5 is half-height — the diamond prints 2×rows-1 = 9 lines.

Setup
2

Print top half

for (let i = 1; i <= rows; i++) — Program 57 pyramid logic with left and right diagonal inner loops.

Top half
3

Print bottom half

for (let i = rows - 1; i >= 1; i--) — same inner loops, counting down to avoid repeating the peak row.

Bottom half
4

Diagonal logic per row

Left j = rows..1, right k = 2..rows — append digit when i === j or i === k, else space.

Diagonals
=

Diagonal mirror diamond complete

2×rows-1 lines total — O(n²) time, O(1) extra memory.

🔎 Worked Walkthrough — rows = 5

Trace each line’s half (top or bottom), row index, and diagonal hits — nine lines total.

LineHalfiLeft hitRight hit
1Top1j=1(none)
2Top2j=2k=2
3Top3j=3k=3
4Top4j=4k=4
5Top (peak)5j=5k=5
6Bottom4j=4k=4
7Bottom3j=3k=3
8Bottom2j=2k=2
9Bottom1j=1(none)

The bottom loop starts at rows-1 so line 5 (peak) is not printed twice — total lines = 2×rows-1.

Use Cases

Where this tiny pattern (and its loop structure) shows up beyond the homework prompt.

1. Teaching Nested Loops

Two inner loops with conditional printing — classic diagonal placement drill.

Example: trace each row in the walkthrough table — left hit, right hit.

2. Diagonal Drills

Each row mirrors digits on two diagonals — compare with Program 53’s single diagonal V-shape.

Example: row 5 prints 5 at column 5 and again at column 9.

3. Output Formatting Drills

Practice building one line string per row with digit-or-space decisions per column.

Example: call console.log() inside the inner loop by mistake.

4. Why k starts at 2

Starting the right loop at 2 avoids a third digit at the center — keeps exactly two prints per row.

Example: try k = 1 and see the center digit triple on some rows.

5. Complexity Intuition

Each row scans about 2n positions — makes O(n²) concrete for beginners.

Example: row 5 with rows = 5 scans 9 character slots — see the walkthrough table.

6. Input Validation Labs

Pair the pattern with Number.isFinite and positive-row validation after parseInt(prompt()).

Example: reject rows <= 0 and re-prompt.

Pro Tip: when an interviewer asks for patterns, explain outer/inner roles first — then write the loops. The story matters as much as the code.

Advantages

Why this pattern earns a permanent spot in beginner JavaScript courses.

  1. 1. Instant Visual Feedback

    The full diamond is instantly recognizable — top half grows, bottom half mirrors symmetrically.

  2. 2. Real Math Connection

    Conditional digit-or-space printing teaches real console alignment — not abstract loop drill.

  3. 3. Easy to Extend

    Swap digits for * to get an X-diamond, or try fixed-width formatting for rows beyond 9.

  4. 4. O(1) Extra Memory

    Streaming output needs no storage beyond loop counters.

Pro Tip: trace rows = 3 on paper — 5 lines total, peak at row 3, then mirror back to 1.

Usage Tips

Small habits that keep number-pattern code clean.

  1. 1. Left loop: j = rows..1

    Append the digit when i === j; otherwise append a single space.

  2. 2. Validate User Input

    Avoid crashing when the user types letters instead of a number.

  3. 3. Newline After Both Inner Loops

    Only call console.log(line) after both inner loops finish the row.

  4. 4. Right loop starts at k = 2

    Use for (let k = 2; k <= rows; k++) so the center position is not duplicated.

  5. 5. Dry-Run rows = 5

    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 called console.log() inside the inner loop.

Common Pitfalls

Mistakes that commonly break diagonal mirror number diamond patterns.

  1. 1. console.log() Inside Inner Loop

    Each digit lands on its own line — you get a column, not a pyramid.

    → Use line += (i === j) ? i : " "; call console.log(line) only after both inner loops.

  2. 2. Right Loop Starts at 1

    Starting at k = 1 can print a third digit at the center — row looks crowded.

    → Use for (let k = 2; k <= rows; k++) — mirror from column 2 onward.

  3. 3. Wrong Condition Check

    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.

  4. 4. Forgetting Newline After Row

    All numbers print on one long line without row breaks.

    → Call console.log(line) after both inner loops complete.

  5. 5. Unchecked parseInt(prompt())

    Letters or empty input yield NaN or leave rows invalid.

    → Validate with Number.isFinite(rows) and check rows >= 1 before drawing.

Edge Cases

Check these inputs before calling the solution done.

rows = 1

Single row

Output is just 1 — the right loop (k = 2..1) does not run.

rows = 0

Empty output

Outer loop never runs — print nothing or show a message.

Negative

rows < 0

Treat as invalid; re-prompt instead of silent empty output.

rows = 5

Compact trace

Bottom row has two copies of 5 across 9 positions — good for dry-runs before scaling up.

Bad input

Non-numeric input

Bare parseInt(prompt()) returns NaN — validate with Number.isFinite.

Large rows

Wide output

Row 9 scans 17 character positions (2×9-1) — total work grows as O(n²).

🎯 Practice Problems

Try these variations to lock in the pattern.

1. Compare with Program 57

  • Program 57 prints only the top pyramid half
  • Program 58 adds bottom loop rows-1..1 for the full diamond

2. Avoid duplicate peak

  • Try starting bottom loop at rows and see the middle row print twice
  • Fix by starting at rows-1

3. Next in series

  • Continue with Program 59
  • Build on diagonal mirror patterns

4. Character swap

  • Replace digit appends with "*" in both diagonal branches
  • Same loops, clean X-diamond for visual debugging

Notes

  • Two outer loops. Top: i = 1..rows. Bottom: i = rows-1..1. Same inner diagonal logic in both.
  • Build one line string per row with += — call console.log(line) only after both inner loops finish.
  • Validate rows > 0 for interactive programs; rows = 1 prints one line — bottom loop does not run.
  • Diamond has 2×rows-1 lines, each scanning about 2×rows-1 positions — total work grows as O(n²).

Quick Takeaway: top 1..rows, bottom rows-1..1, same inner diagonal logic, then console.log(line).

⏱️ Time and Space Complexity

ProgramTimeExtra space
Nested loops (Examples 1–3)O(n²)O(1)
Digits on row i2i - 1No storage beyond loop counters
Wrap Up

🎉 Conclusion

The diagonal mirror number diamond is a natural follow-up to Program 57: one extra outer loop mirrors the pyramid into a full symmetric diamond. Master the fixed-rows version, then try user input and the compact 3-row trace.

Practice the three examples above, then continue to Program 59 for the next pattern in the series.

Total output is 2×rows-1 lines — peak at row rows, then mirrored descent to 1.

💡 Best Practices

✅ Do

  • Left: for (let j = rows; j >= 1; j--) with if (i === j)
  • Right: for (let k = 2; k <= rows; k++) with if (i === k)
  • Append a single space for non-matching positions
  • Call console.log(line) after both inner loops
  • Use Number.isFinite after parseInt(prompt()) for user input

❌ Don’t

  • Start right loop at k = 1 — can triple-print at center
  • Use j === rows instead of i === j — wrong diagonal
  • Call console.log() inside any inner loop
  • Ignore bad console input in user-facing demos
  • Skip the rows = 3 dry-run before coding rows = 5

Key Takeaways

Knowledge Unlocked

Five things to remember about this diagonal mirror diamond

Print the full mirror-diagonal diamond the beginner-friendly way.

5
Core concepts
02

Left

j = rows..1

Code
03

Right

k = 2..rows

Code
04

Check

i === j or i === k

Logic
O 05

Complexity

O(n²) time

Analysis

❓ Frequently Asked Questions

Each row prints the same digit on the left diagonal and the right diagonal; spaces fill the remaining positions.
The top half already printed row rows at the peak — starting at rows-1 avoids duplicating the middle line.
An inverse-V pyramid from 1 to rows, then mirrored back down to 1 — 2*rows-1 lines total.
Program 57 prints only the top pyramid half. Program 58 adds a second outer loop from rows-1 down to 1 for the bottom half.
Each column position gets either the row digit or a space — the conditions pick exactly two append positions per row.
Change rows or read it from user input with prompt() and parseInt — see Example 2.
O(n²) for n rows because you log 2n-1 lines, each scanning about 2n positions.
Yes. Replace the digit with '*' in both diagonal append branches.
Use parseInt with Number.isFinite. Bare parseInt(prompt()) returns NaN on bad input.
Only one line logs — the bottom loop (rows-1..1) does not run.

Did you Know? 🔊

Print the Program 57 pyramid for the top half, then mirror with for (let i = rows - 1; i >= 1; i--). Total lines = 2×rows-1 — each row scans about 2×rows-1 positions.

Continue to Program 59

Move on to the next pattern in the JavaScript number-pattern series.

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