JavaScript Reverse Number Triangle Pattern (Growing)
Beginner
5 min read
Updated: Sep 2026
3 programs
Live preview
Definition
What Is This Pattern?
A reverse row number triangle grows one digit per row, but each row logs digits downward from the row index to 1 — 1, 21, 321, and so on.
Remember
Rule: for i from 1 to rows
for j from i down to 1: append j (no space)
1
21
321
4321
54321 ← rows = 5
Follows the reverse ascending triangle in Program 6; next is the reverse left-growing triangle in Program 8.
Approach
How to Solve It
Outer loop counts up from 1 to rows. Inner loop counts down from i to 1. End each row with console.log(line).
Method
Idea
Best for
Ascending outer + descending inner
Outer i = 1..rows; inner j = i..1; append j
Learning, interviews, exams
Spaced digits
line += j + " " instead of line += j
Easier reading on each row
Pseudocode
Pseudocode
for i from 1 to rows:
line = ""
for j from i down to 1:
line += j
print line
Cheat sheet
Goal
Pattern
Pick each row
for (let i = 1; i <= rows; i++)
Append digits
for (let j = i; j >= 1; j--) line += j;
End of row
console.log(line);
Spaced form
line += j + " ";
vs Program 5 / 6
5: 1..i; 6: i..rows; 7: i..1
Printing Numbers vs Starting a New Line
API
Effect
Use for
line += j
Stays on the same row
Each digit on the row
console.log(line)
Ends the current row
After the inner loop finishes
Append digits without a newline, then end the row once.
Try it
Live Preview
Change the row count and the reverse-row triangle updates instantly — capped at 9 for readable single-digit demos.
Whole numbers from 1 to 9. Tap a chip or type a value — the preview redraws as you go.
Live resultrows = 5 · 15 digits
1
21
321
4321
54321
Trace
Worked Walkthrough
Trace rows = 5 — a descending inner loop reverses each row while the outer loop grows the width.
i
Inner j
Prints
1
1..1
1
2
2..1
21
3
3..1
321
5
5..1
54321
Total digits = n(n+1)/2 → O(n²). Compare with Program 5 (1..i) and Program 6 (i..rows).
Code
JavaScript Programs
Three complete programs: fixed rows = 5, prompt input, and a compact rows = 3 demo. Use View Output for samples, or Try It Yourself to edit and run live.
Example 1 — Fixed rows = 5
Hard-coded height — outer counts up, inner appends i..1 with no spaces.
JavaScript
const rows = 5;
for (let i = 1; i <= rows; i++) {
let line = "";
for (let j = i; j >= 1; j--) {
line += j;
}
console.log(line);
}
1. Outer up.i grows from 1 to 5, so each row is one digit wider.
2. Inner down.j starts at i and decrements to 1 — that reverses the digits.
3. Newline. Call console.log(line) only after the inner loop finishes the row.
Example 2 — User Input Rows
Read rows with prompt, validate, then run the same nested loops.
JavaScript
const rows = parseInt(prompt("Enter the number of rows:"), 10);
if (!Number.isFinite(rows) || rows <= 0) {
console.log("Please enter a positive integer.");
} else {
for (let i = 1; i <= rows; i++) {
let line = "";
for (let j = i; j >= 1; j--) {
line += j;
}
console.log(line);
}
}
2. Trace on paper. Confirm each new digit is prepended on the left of the descending sequence.
3. Scale up next. Once the small demo is clear, use Examples 1–2 for five rows or user input.
Edge Cases & Pitfalls
Check these before calling the solution done.
j = 1..i
Got Program 5 instead
If the inner loop counts up from 1 to i, you get 1, 12, 123… Keep j = i; j >= 1; j--.
i = rows..1
Wrong outer direction
A descending outer with inner i..rows is Program 6. Program 7 needs outer 1..rows and inner i..1.
log inside
Broken rows
If console.log sits inside the inner loop, each digit lands on its own line. Call it only after the row finishes.
rows = 1
Single digit
Output is just 1 — a good sanity check for input validation.
rows > 9
Multi-digit width
Digits 10+ make tight rows hard to read. Cap demos at 9 or switch to spaced j + " ".
Bad input
Validate parseInt
Check Number.isFinite(rows) && rows > 0 before the loops.
Analysis
Time and Space Complexity
Program
Time
Extra space
Fixed / compact (Examples 1, 3)
O(n²)
O(1)
User input (Example 2)
O(n²)
O(1)
Total digits appended = 1 + 2 + … + n = n(n+1)/2 → O(n²) time. Only a few loop variables are needed.
Remember
Key Takeaways
Grow then reverse: outer 1..rows, inner i..1.
Start at i: the first digit on each row is the row index itself.
Break the row:line += j in the inner loop; console.log(line) after it.
Complexity:O(n²) time from n(n+1)/2 digits; O(1) extra space.
One line: count i up to rows, append j from i down to 1, then log the line.
Frequently Asked Questions
A reverse row number triangle: row 1 shows 1, row 2 shows 21, row 3 shows 321, and so on until the last row shows digits from rows down to 1.
The inner loop uses for (let j = i; j >= 1; j--) which appends i, i-1, ..., 1 on each row.
When i = rows (5), the inner loop appends j from 5 down to 1 — giving 54321 on the last line.
Program 6 outer counts down and logs i..rows (5, 45, 345). Program 7 outer counts up and logs i down to 1 (1, 21, 321).
Program 5 logs 1..i ascending per row. Program 7 logs i..1 descending per row.
line += appends digits on the same row. console.log(line) ends the row after the inner loop finishes.
Change rows or read it from user input with prompt() and parseInt — see Example 2.
Yes — use for (let j = 1; j <= i; j++) in the inner loop like Program 5.
O(n²) for n rows because total appends are 1 + 2 + ... + n = n(n+1)/2.
Use parseInt with Number.isFinite after prompt(). Bare parseInt(prompt()) returns NaN on bad input.
🤔
Did you know?
Each row logs digits in reverse order — outer i runs 1..rows, inner j counts down from i to 1 — producing 1, 21, 321, and so on. Total appends grow as O(n²).