JavaScript Number Triangle Pattern (Reverse Descending)
Beginner
5 min read
Updated: Sep 2026
3 programs
Live preview
Definition
What Is This Pattern?
A reverse descending triangle shortens each row from the top — 54321, 4321, 321, 21, 1 — with digits counting down on every line.
Remember
Rule: for i = rows down to 1
print digits i..1
54321
4321
321
21
1 ← rows = 5
After Program 2’s left-shifted i..n rows, this one flips both loops downward so each row reads in reverse.
Approach
How to Solve It
Count i down from rows; on each row, append digits from i down to 1.
Method
Idea
Best for
Nested loops
Outer i = rows..1; inner j = i..1
Learning, interviews
prompt input
Same loops; read rows at runtime
Interactive practice
Spaced digits
line += j + " "
Readable output
Pseudocode
Pseudocode
for i from rows down to 1:
line = ""
for j from i down to 1:
line += j
print line (with newline)
Cheat sheet
Goal
Pattern
Set size
const rows = 5;
Outer loop
for (let i = rows; i >= 1; i--)
Inner loop
for (let j = i; j >= 1; j--) line += j;
End row
console.log(line);
Digits printed
i..1 (length i)
Spaced
line += j + " ";
Printing Numbers vs Starting a New Line
API
Effect
Use for
line += j
Stays on the same row
Each 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 reverse descending 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
54321
4321
321
21
1
Trace
Worked Walkthrough — rows = 3
Trace each outer value of i and the digits printed from i down to 1.
i
Digits i..1
Printed row
3
3 2 1
321
2
2 1
21
1
1
1
As i falls, the inner loop starts lower — one fewer digit each row.
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 — outer shrinks the row; inner prints digits in reverse.
JavaScript
const rows = 5;
for (let i = rows; i >= 1; i--) {
let line = "";
for (let j = i; j >= 1; j--) {
line += j;
}
console.log(line);
}
1. Outer loop.i runs from 5 down to 1 — the starting digit and row length.
2. Inner loop.j runs from i down to 1, so line += j builds i..1.
3. Newline.console.log(line) after the inner loop prints the row and starts the next one.
Example 2 — prompt Input
Read rows at runtime with prompt and parseInt.
JavaScript
const rows = parseInt(prompt("Enter the number of rows:"), 10);
if (!Number.isFinite(rows) || rows < 1) {
console.log("Please enter a positive integer.");
} else {
for (let i = rows; i >= 1; i--) {
let line = "";
for (let j = i; j >= 1; j--) {
line += j;
}
console.log(line);
}
}
1. Same structure. Outer and inner bounds match Example 1.
2. Only append changes. Use line += j + " " instead of line += j.
3. Same shape. Values and row count stay the same — only spacing differs.
Edge Cases & Pitfalls
Check these before calling the solution done.
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 inner loop.
j++
Ascending by mistake
Using j = 1..i with a descending outer loop yields 12345, 1234, … — that is Program 1, not this pattern.
print(i)
Repeated digit
Appending i instead of j prints a repeated row digit, not a countdown.
rows = 1
Single digit
Output is just 1 on one line.
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: outer i = rows..1; inner prints i..1.
Both count down: outer shrinks the row; inner reverses the digits.
Write vs log:line += j builds; console.log(line) breaks.
Complexity:O(n²) for n rows.
One line: shrink the outer count while the inner loop prints each row backwards from i to 1.
Frequently Asked Questions
The inner loop runs for (let j = i; j >= 1; j--), so each row appends i, i-1, ..., 1.
Because rows = 5 and the outer loop starts with i = rows. The first row appends from 5 down to 1.
Program 2 prints i..rows (left-shifted ascending). Program 3 prints i..1 (reverse descending) with a shrinking outer loop.
Keep the descending outer loop but change the inner loop to for (let j = 1; j <= i; j++) (ascending) — that is Program 1’s shape.
Replace 5 with rows in the outer bound — see Example 2.
Use line += j + " " instead of line += j — see Example 3.
O(n²) for n rows. Total appends are n + (n-1) + ... + 1 = n(n+1)/2.
Use parseInt with Number.isFinite so bad input does not produce NaN.
Only one row prints — a single 1.
🤔
Did you know?
This pattern prints each row in descending order from i down to 1. The outer loop shrinks the row length while the inner loop counts downward — producing 54321, 4321, 321, and so on.