A reverse alphabet triangle grows one letter per row, but each row starts at the current letter and counts down to A.
Remember
Rule: row i prints (A+i) .. A descending
A
BA
CBA
DCBA
EDCBA ← 5 rows
Compare Program 1 (ascends from A: A, AB, ABC) and Program 3 (start moves back, letters still run forward). Program 5 shrinks row width from ABCDE to A.
Approach
How to Solve It
Outer loop picks the start letter; inner loop counts down to A with range(..., -1).
Method
Idea
Best for
Nested ord/chr
range(base + i, base - 1, -1)
Learning descending bounds
String slice
letters[i::-1]
Compact shortcut once the idea clicks
Pseudocode
Pseudocode
base = 'A'
for i from 0 to rows - 1:
for code from (base + i) down to base: // inclusive A
print code
print newline
Cheat sheet
Goal
Pattern
Walk rows
for i in range(rows):
Count down to A
for code in range(base + i, base - 1, -1):
Print letter
print(chr(code), end="")
Include A
Stop at base - 1 (exclusive end)
End the row
print()
Slice shortcut
print(letters[i::-1])
vs Program 1
Here the inner loop goes down; Program 1 goes up
Printing Letters vs Starting a New Line
API
Effect
Use for
print(chr(code), end="")
Stays on the same row
Each letter in the descending run
print()
Ends the current row
After the inner loop
Print letters without a newline, then end the row once.
Try it
Live Preview
Change the row count and the reverse triangle updates instantly — every row still ends at A.
Whole numbers from 1 to 10. Size 5 means the last row starts at E. Tap a chip or type a value — the preview redraws as you go.
Live result5 rows · last EDCBA
A
BA
CBA
DCBA
EDCBA
Trace
Worked Walkthrough — rows = 3
Start letter grows A → B → C; each inner run ends at A.
i
Inner run
Printed row
0
A..A
A
1
B..A
BA
2
C..A
CBA
Total letters are 1+2+…+n = n(n+1)/2 → O(n²).
Code
Python Programs
Three complete programs: fixed height, row-count input(), and a reverse-slice shortcut. Use View Output for sample results.
Example 1 — Fixed rows = 5
Outer loop picks the start; inner loop counts down to A.
Python
rows = 5
base = ord("A")
for i in range(rows):
for code in range(base + i, base - 1, -1):
print(chr(code), end="")
print()
Output
A
BA
CBA
DCBA
EDCBA
How It Works
1. Pick the start. When i = 2, start is base + 2 (C).
2. Count down.range(base + i, base - 1, -1) prints C, B, A — the exclusive end base - 1 includes A.
3. Newline. Bare print() after the inner loop starts the next row.
Example 2 — Row Count Input
Read how many rows to print. Cap at 26 so letters stay in A–Z.
Python
raw = input("Enter the number of rows (max 26): ").strip()
try:
rows = int(raw)
except ValueError:
print("Please enter a whole number.")
raise SystemExit(1)
rows = max(1, min(rows, 26))
base = ord("A")
for i in range(rows):
for code in range(base + i, base - 1, -1):
print(chr(code), end="")
print()
Output (when user enters 4)
A
BA
CBA
DCBA
How It Works
1. Validate rows. Parse an integer, then clamp to 1..26.
2. Same descending core. Four rows end at DCBA; every row still finishes on A.
Example 3 — letters[i::-1]
Reverse-slice from index i to the start of the alphabet string.
Python
rows = 5
letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
for i in range(rows):
print(letters[i::-1])
Output
A
BA
CBA
DCBA
EDCBA
How It Works
1. One slice.letters[i::-1] returns letters from index i down to 0.
2. Same shape. Identical output to Example 1 — keep the nested-loop version for exams that ask for descending bounds.
Edge Cases & Pitfalls
Check these before calling the solution done.
skip A
range(..., base, -1)
range stops before the end value, so ending at base skips A. Use base - 1.
wrong direction
Inner loop goes up
Ascending from A gives Program 1 (A, AB, ABC). Keep step -1 for this pattern.
newline early
Bare print() inside the inner loop
Use end="" for letters; call bare print() only after the descending run.
rows > 26
Letter past Z
Cap rows at 26 so base + i stays in A–Z.
rows = 1
Single A
Output is just A — a good sanity check.
Bad input
Non-integer rows
Catch ValueError from int(...) before the outer loop.
Analysis
Time and Space Complexity
Program
Time
Extra space
Nested loops (Examples 1–2)
O(n²)
O(1)
Slice shortcut (Example 3)
O(n²)
O(n) per row for the slice string
There are n rows and row i prints i+1 letters, so total work is n(n+1)/2.
Remember
Key Takeaways
Rule: row i prints (A+i)..A descending.
Inclusive A: stop the range at base - 1, not base.
Contrast: Program 1 goes up from A; this pattern goes down to A.
Next step: Program 5 shrinks ascending rows from ABCDE to A.
One line: for each row i, print letters from A+i down to A.
Frequently Asked Questions
The outer loop picks the row index i (0-based). The inner loop walks letter codes from ord('A') + i down to ord('A') using range(base + i, base - 1, -1), so row 0 is A, row 1 is BA, row 2 is CBA, and so on.
range stops before its end value. Using base - 1 as the exclusive stop ensures the last printed code is base (letter A). Stopping at base would skip A on every row.
print(chr(code), end="") stays on the same line. print() ends the current line. Letters use end=""; the row break uses print() after the inner loop.
Program 1 ascends from A on every row (inner loop goes up). This pattern starts at the current row letter and counts down to A (inner loop goes down with step -1).
O(n²) where n is the number of rows. Total printed characters equal 1+2+…+n = n(n+1)/2 — same triangular count as Program 1.
Yes. Keep letters = "ABCDEFG..." and print(letters[i::-1]) for each row index i. Nested ord/chr loops teach the bounds; reverse slicing is a compact shortcut.
Use try/except ValueError around int(input()), then clamp rows between 1 and 26 so letter codes stay within A–Z.
Letter codes walk past Z and print unexpected characters. Clamp to 26 for A–Z demos, or define a clear error/wrap policy.
🤔
Did you know?
Row index i (0-based) prints letters from chr(ord('A') + i) down to A using range(base + i, base - 1, -1). Total letters for n rows is still n(n+1)/2 — compare Program 1 (ascending from A each row) and Program 5 (decreasing row width from ABCDE to A).