JavaScript Descending Number Triangle Pattern (Left-Aligned)
Beginner
5 min read
Updated: Sep 2026
3 programs
Live preview
Definition
What Is This Pattern?
A left-aligned descending triangle prints rows that always start at the maximum digit and count down — but each row stops one digit sooner, so the triangle shrinks from the right.
Remember
Rule: for i = 0..rows-1
print rows down to i+1
54321
5432
543
54
5 ← rows = 5
Unlike Program 3’s i..1 rows (starting digit shrinks), every row here begins at rows.
Approach
How to Solve It
Walk i from 0 to rows - 1; always start the inner loop at rows and stop after i.
Method
Idea
Best for
Fixed start
Inner j = rows..i+1 via j > i
Learning, interviews
prompt rows
Same loops; read rows at runtime
Interactive practice
Spaced digits
Same bounds; line += j + " "
Readable console output
Pseudocode
Pseudocode
for i from 0 to rows - 1:
line = ""
for j from rows down while j > i:
line += j
print line
Cheat sheet
Goal
Pattern
Set rows
const rows = 5;
Outer loop
for (let i = 0; i < rows; i++)
Inner loop
for (let j = rows; j > i; j--)
Append digit
line += j;
End row
console.log(line);
Digits per row
rows - i
vs Program 3
Always start at rows vs start at i
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 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
5432
543
54
5
Trace
Worked Walkthrough — rows = 3
Trace each outer i, the inner j values, and the printed row.
i
Inner j (j > i)
Printed row
0
3 2 1
321
1
3 2
32
2
3
3
Every row starts at 3. Digits per row = rows - i. Total = 6 = 3×4/2.
Code
JavaScript Programs
Three complete programs: fixed rows = 5, prompt rows, 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 — inner loop always starts at rows and shrinks the stop.
JavaScript
const rows = 5;
for (let i = 0; i < rows; i++) {
let line = "";
for (let j = rows; j > i; j--) {
line += j;
}
console.log(line);
}
1. Same structure. Outer and inner bounds match Example 1.
2. Only the append changes.line += j + " " adds a trailing space after each digit.
3. Shape unchanged. Still left-aligned and shrinking from the right.
Edge Cases & Pitfalls
Check these before calling the solution done.
fixed stop
Full rectangle
If the inner loop always runs to 1, every row prints the same length. The stop must depend on i.
wrong outer
Program 3 shape
A descending outer loop with j = i..1 yields Program 3, not this fixed-start triangle.
log inside
Vertical digits
If console.log is inside the inner loop, each digit lands on its own line.
rows = 1
Single digit
Output is just 1 — one outer iteration, one inner append.
multi-digit
Values above 9
When rows > 9, cells become two characters. Keep demos at rows ≤ 9 or use spacing.
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
Digits per pattern = n + (n-1) + … + 1 = n(n+1)/2 → O(n²).
Remember
Key Takeaways
Rule: always start at rows; stop sooner each row with j > i.
Left-aligned: no leading spaces — the triangle shrinks from the right.
Write vs log:line += j builds; console.log(line) breaks.
Complexity: total digits = n(n+1)/2 → O(n²).
One line: start every row at the max digit and drop one from the end each time.
Frequently Asked Questions
Because the inner loop always begins at rows (the maximum digit) and counts down. Only the stopping point changes per row.
Row i (0-based) appends rows - i digits — the inner loop runs for (let j = rows; j > i; j--).
Program 3 appends i..1 with a descending outer loop (4321, 321, …). Program 4 appends rows..i+1 with an ascending outer loop — every row starts at rows.
No — digits are left-aligned with no leading spaces. Each row begins flush left at the maximum digit.
Replace 5 with rows in the outer loop bound — see Example 2.
Use line += j + " " instead of line += j — see Example 3.
O(n²) for n rows because total appends are 1 + 2 + … + n = n(n+1)/2.
Use parseInt with Number.isFinite so bad input does not produce NaN.
Only one row prints — a single digit matching rows.
🤔
Did you know?
Each row starts at rows and counts down to a shrinking limit. Row i (0-based) appends rows - i digits — total appends = n(n+1)/2; output is left-aligned with no leading spaces.