A reverse row number triangle grows one digit per row, but each row prints 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: print 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 a bare print().
Method
Idea
Best for
Ascending outer + descending inner
Outer i = 1..rows; inner j = i..1; print j
Learning, interviews, exams
Spaced digits
print(str(j) + " ", end="") instead of print(j, end="")
Easier reading on each row
Pseudocode
Pseudocode
for i from 1 to rows:
for j from i down to 1:
print j
print newline
Cheat sheet
Goal
Pattern
Pick each row
for i in range(1, rows + 1):
Print digits
for j in range(i, 0, -1): print(j, end="")
End of row
print()
Spaced form
print(str(j) + " ", end="")
vs Program 5 / 6
5: 1..i; 6: i..rows; 7: i..1
Printing Numbers vs Starting a New Line
API
Effect
Use for
print(j, end="")
Stays on the same line
Each digit on the row
print()
Ends the current line
After the inner loop finishes
Digits use end=""; a bare print() ends 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 — rows = 5
Trace how 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
Python Programs
Three complete programs: fixed rows = 5, user-input rows, and a compact rows = 3 demo. Use View Output to reveal sample results.
Example 1 — Fixed rows = 5
Hard-coded height — outer counts up, inner prints i..1 with no spaces.
Python
rows = 5
for i in range(1, rows + 1):
for j in range(i, 0, -1):
print(j, end="")
print()
Output
1
21
321
4321
54321
How It Works
1. Outer up.i grows from 1 to 5, so each row is one digit wider.
2. Inner down.range(i, 0, -1) starts at i and steps to 1 — that reverses the digits.
3. Newline. Call bare print() only after the inner loop finishes the row.
Example 2 — User Input Rows
Read rows safely, validate, then run the same nested loops.
Python
try:
rows = int(input("Enter the number of rows: "))
except ValueError:
print("Please enter a positive integer.")
raise SystemExit
if rows <= 0:
print("Please enter a positive integer.")
raise SystemExit
for i in range(1, rows + 1):
for j in range(i, 0, -1):
print(j, end="")
print()
Output (when user enters 4)
Enter the number of rows: 4
1
21
321
4321
How It Works
1. Prompt and validate. Catch ValueError; reject non-positive values before looping.
2. Same core. Outer up / inner i..1 matches Example 1 — only rows comes from the user.
3. Safer input tip. Cap demos for readable single-digit output:
Safer input
try:
rows = int(input("Enter the number of rows: "))
except ValueError:
print("Enter a whole number from 1 to 9.")
raise SystemExit
if rows < 1 or rows > 9:
print("Enter a whole number from 1 to 9.")
raise SystemExit
Example 3 — Compact rows = 3
Same structure with only three rows — easy to trace on paper.
Python
rows = 3
for i in range(1, rows + 1):
for j in range(i, 0, -1):
print(j, end="")
print()
Output
1
21
321
How It Works
1. Three rows.i = 1 → 1; i = 2 → 21; i = 3 → 321.
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 range(i, 0, -1).
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.
print inside
Broken rows
If bare print() 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 print(str(j) + " ", end="").
ValueError
Validate input
Use try/except ValueError and require rows > 0 before looping — bad input should not crash.
Analysis
Time and Space Complexity
Program
Time
Extra space
Fixed / input (Examples 1–2)
O(n²)
O(1)
Compact rows = 3 (Example 3)
O(n²)
O(1)
Total digits printed = 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:print(j, end="") in the inner loop; bare print() after it.
Complexity:O(n²) time from n(n+1)/2 digits; O(1) extra space.
One line: count i up to rows, print j from i down to 1, then newline.
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 starts at j = i and decrements to 1 — printing i, i-1, ..., 1 on each row.
When i = rows (5), the inner loop prints j from 5 down to 1.
Program 6 outer counts down and prints i..rows (5, 45, 345). Program 7 outer counts up and prints i down to 1 (1, 21, 321).
Program 5 prints 1..i ascending per row. Program 7 prints i..1 descending per row.
print(j, end="") stays on the same line. print() ends the row after the inner loop.
Change rows or read it from user input with int(input()) inside try/except — see Example 2.
O(n²) for n rows because total prints are 1 + 2 + ... + n = n(n+1)/2.
🤔
Did you know?
Each row prints 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 prints grow as O(n²).