JavaScript Number Triangle Pattern (Bidirectional)
Beginner
5 min read
Updated: Sep 2026
3 programs
Live preview
Definition
What Is This Pattern?
A bidirectional number triangle prints a repeated digit on each shrinking row — digits rise (1, 2, 3) then mirror down (2, 1).
Remember
Rule: row i repeats val, length = rows − i + 1
val = i if i < rows − 1
else rows + 1 − i
11111
2222
333
22
1 ← rows = 5
Shrinking length plus a mapped digit — a clear follow-up after the centered pyramid in Program 24.
Approach
How to Solve It
Outer i = 1..rows; pick the row digit; inner j = i..rows repeats that digit.
Method
Idea
Best for
if/else mapping
Rise then rows + 1 − i
Learning, interviews
prompt + ternary
Same loops; generalize for any rows
Interactive practice
Spaced digits
line += val + " "
Readable output
Pseudocode
Pseudocode
for i from 1 to rows:
if i < rows - 1:
val = i
else:
val = rows + 1 - i
line = ""
for j from i to rows:
line += val
print line (with newline)
Cheat sheet
Goal
Pattern
Set rows
const rows = 5;
Outer loop
for (let i = 1; i <= rows; i++)
Pick digit
const val = i < rows - 1 ? i : rows + 1 - i;
Shrink row
for (let j = i; j <= rows; j++) line += val;
End row
console.log(line);
Spaced
line += val + " ";
Printing Numbers vs Starting a New Line
API
Effect
Use for
line += val
Stays on the same row
Each repeated digit
console.log(line)
Ends the line
After the inner loop
Build the row with +=, then break once with console.log. Putting console.log inside the inner loop prints one digit per line.
Try it
Live Preview
Change the row count and the bidirectional triangle updates instantly.
Whole numbers from 1 to 9. Tap a chip or type a value — the preview redraws as you go.
Live resultrows = 5 · digits = 15
11111
2222
333
22
1
Trace
Worked Walkthrough — rows = 4
Trace each i, the mapped digit, and how many times it repeats.
i
val
Repeats
Printed row
1
1 (i < 3)
4×
1111
2
2 (i < 3)
3×
222
3
2 (4 + 1 − 3)
2×
22
4
1 (4 + 1 − 4)
1×
1
The switch happens when i >= rows − 1 — that is when the digit starts mirroring down.
Code
JavaScript Programs
Three complete programs: fixed rows = 5, prompt input, and spaced digits. Use View Output for sample results, or Try It Yourself to edit and run in the playground.
Example 1 — Fixed rows = 5
Hard-coded height — if/else picks the digit; the inner loop shrinks each row.
JavaScript
const rows = 5;
for (let i = 1; i <= rows; i++) {
let line = "";
for (let j = i; j <= rows; j++) {
if (i < 4) {
line += i;
} else {
line += rows + 1 - i;
}
}
console.log(line);
}
1. Prompt and parse. Convert the answer with parseInt(..., 10).
2. Validate first. Reject NaN or non-positive values before looping.
3. General mapping.i < rows − 1 ? i : rows + 1 − i replaces the hard-coded i < 4.
Example 3 — Spaced Digits
Keep rows = 5 but append a space after each digit for easier reading.
JavaScript
const rows = 5;
for (let i = 1; i <= rows; i++) {
const val = i < rows - 1 ? i : rows + 1 - i;
let line = "";
for (let j = i; j <= rows; j++) {
line += val + " ";
}
console.log(line);
}
1. Same structure. Outer loop, mapping, and shrinking inner loop match Example 2.
2. Only append changes. Use line += val + " " instead of line += val.
3. Same shape. Row lengths and digit values are unchanged — only spacing differs.
Edge Cases & Pitfalls
Check these before calling the solution done.
j = 1
Rows do not shrink
Starting the inner loop at j = 1 keeps every row length rows. Use j = i.
hard 4
Hard-coded threshold
i < 4 only fits rows = 5. Prefer i < rows − 1 for other sizes.
log inside
Vertical digits
If console.log is inside the inner loop, each digit lands on its own line. Append with +=; log only after the loop.
rows = 1
Single digit
Output is just 1 — the mirror branch still yields rows + 1 − i = 1.
rows ≤ 0
Empty output
The outer loop never runs. Guard prompt input with rows >= 1.
NaN input
Validate parseInt
Letters or empty prompt yield NaN — check Number.isFinite(rows) && rows >= 1.
Analysis
Time and Space Complexity
Program
Time
Extra space
Examples 1–3
O(n²)
O(n) for the current line string
Total digits = n + (n−1) + … + 1 = n(n+1)/2 → O(n²).
Remember
Key Takeaways
Rule: shrink with j = i..rows; map digit up then down.
Mapping:val = i < rows − 1 ? i : rows + 1 − i.
Write vs log:line += val builds; console.log(line) breaks.
Complexity:O(n²) for n rows.
One line: shrink the row from the left, and flip the printed digit after the peak with rows + 1 − i.
Frequently Asked Questions
For i = 5 and rows = 5, the condition i < rows − 1 is false, so the program uses rows + 1 − i, which equals 1.
Because the inner loop runs from j = i to rows. As i increases, the inner loop executes fewer times.
Digits rise (1, 2, 3) on early rows then mirror down (2, 1) on the last rows via the rows + 1 − i mapping.
line += val repeats the digit on the same line. console.log(line) ends the row after the inner loop finishes.
A single inner loop with a digit mapping keeps the shrinking row logic in one place.
Use val = i < rows − 1 ? i : rows + 1 − i (see Example 2).
O(n²) for n rows because total prints are triangular (n + (n−1) + … + 1).
Use parseInt(prompt(...), 10) and check Number.isFinite(rows) && rows >= 1 so bad input does not produce NaN.
Only one row prints — a single 1.
🤔
Did you know?
This pattern prints repeated digits per row. The inner loop runs from j = i to rows, shrinking each row. The row digit is i for the first half, then switches to rows + 1 - i to produce 22 and 1.