Shape Rule
Current letter down to A
Row 0 prints A, row 1 prints BA, row 2 prints CBA, up to EDCBA for five rows.

The reverse alphabet triangle grows each row by one letter, but every row counts down to A instead of up from it. This tutorial covers the shape rule, descending inner loop, a live preview, algorithm steps, worked JavaScript examples, edge cases, and complexity.
Current letter down to A
Row 0 prints A, row 1 prints BA, row 2 prints CBA, up to EDCBA for five rows.
Rows
for (let i = 0; i < rows; i++) picks the starting letter for each row (0-based index).
Descending letters
for (let code = base + i; code >= base; code--) prints from the current letter down to A.
Same line / next line
Letters use line += String.fromCharCode(code); end each row with console.log(line).
1–26 rows
Pick a row count and draw the reverse alphabet triangle instantly in the browser.
Complexity
Total letters = n(n+1)/2 — same triangular count as Program 1; extra memory stays O(1).
A reverse alphabet triangle grows by one letter per row, but each line counts down to A instead of up from it. With five rows the console shows A, BA, CBA, DCBA, EDCBA.
in JavaScript you solve it with two nested for loops: the outer loop picks the row index, the inner loop walks letter codes downward with code--, then console.log(line) moves to the next line.
It teaches reverse iteration with code-- and the inclusive stop at code >= base — skills you reuse in inverted patterns, pyramids, and more advanced letter shapes.
On row i, print letters from String.fromCharCode("A".charCodeAt(0) + i) down to A.
for (let code = base + i; code >= base; code--) walks codes downward.
line += String.fromCharCode(code) in the inner loop; console.log(line) after.
Same outer growth — inner direction flips from ascending to descending.
In short: for each row index i from 0 to rows - 1, print letters from String.fromCharCode("A".charCodeAt(0) + i) down to A with line += String.fromCharCode(code), then call console.log(line).
Given a positive integer rows, print a left-aligned reverse alphabet triangle where row i starts at the i-th letter and counts down to A.
// First 5 rows (conceptual shape)
// A
// BA
// CBA
// DCBA
// EDCBA | Item | Type | Description |
|---|---|---|
rows | int | Number of triangle lines to print (typically ≥ 1). |
| Printed output | text | Left-aligned rows; row i (0-based) has letters from String.fromCharCode("A".charCodeAt(0) + i) down to A. |
for i from 0 to rows - 1:
for code from (A + i) down to A:
print letter (no newline)
print newline | Approach | Idea | Best for |
|---|---|---|
| Nested loops (descending inner) | Outer rows + inner codes down to A | Learning and interviews |
letters.slice(0, i + 1).split("").reverse().join("") | Reverse slice for the whole row | Shorter production-style demos |
| Goal | Pattern |
|---|---|
| Walk each row | for (let i = 0; i < rows; i++) |
| Print current letter down to A | for (let code = base + i; code >= base; code--) { line += String.fromCharCode(code); } |
| End the row | console.log(line) |
| One-line row shortcut | console.log(letters.slice(0, i + 1).split("").reverse().join("")) |
| Ascending variant | Inner loop up from A — see Program 1 |
Three ways to emit each row — compare inner-loop direction and the letters.slice(0, i + 1).split("").reverse().join("") shortcut.
A..endfor (code = base; code <= base + i; code++) — row grows from A upward (AB, ABC)
end..Afor (let code = base + i; code >= base; code--) — row starts at current letter and counts down to A
whole rowReverse slice from index i to start — skip the inner loop entirely
loops firstMaster descending code-- before the reverse-slice shortcut
Reach for this pattern when teaching descending inner loops or contrasting with Program 1’s ascending rows.
Natural follow-up after Program 1 — same outer growth, inner loop counts down with step -1.
Practice for (let code = base + i; code >= base; code--) with an immediate visual check.
Combine loops with prompt() for a flexible row count.
Leads to Program 3’s fixed-top rows and Program 5’s decreasing width pattern.
This is a console teaching pattern — not how you build modern app screens.
Key benefit: one small program that locks in reverse inner loops, the inclusive code >= base stop, and O(n²) thinking.
Choose a row count between 1 and 26 and draw the reverse alphabet triangle in the browser.
Three complete JavaScript programs — fixed row count, prompt input, and a slice-reverse shortcut. Click View Output to reveal sample console results, or Try it Yourself to run in the browser editor.
Print five rows with classic nested loops — each row counts down to A.
rows = 5Hard-coded height — ideal for first demos and screenshots.
const rows = 5;
const base = "A".charCodeAt(0);
for (let i = 0; i < rows; i++) {
let line = "";
for (let code = base + i; code >= base; code--) {
line += String.fromCharCode(code);
}
console.log(line);
} When i = 0, the inner loop builds A. When i = 2, it builds CBA, and when i = 4 it builds EDCBA. console.log(line) after the inner loop starts the next row.
Let the user choose the height at runtime.
Read the row count with prompt() and convert with parseInt() (validate with Number.isFinite in real apps).
const rowsInput = prompt("Enter the number of rows (max 26):");
let rows = parseInt(rowsInput, 10);
rows = Math.max(1, Math.min(rows, 26));
const base = "A".charCodeAt(0);
for (let i = 0; i < rows; i++) {
let line = "";
for (let code = base + i; code >= base; code--) {
line += String.fromCharCode(code);
}
console.log(line);
} Same charCodeAt/fromCharCode core as Example 1; only the source of rows changes. The inner loop still counts down to A on every row. Non-numeric input returns NaN with bare parseInt(prompt()) — validate with Number.isFinite for safer labs.
Same shape without an explicit inner letter loop.
letters.slice(0, i + 1) reversedSlice from the start through index i, then reverse for each row.
const rows = 5;
const clampedRows = Math.max(1, Math.min(rows, 26));
const letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
for (let i = 0; i < clampedRows; i++) {
console.log(letters.slice(0, i + 1).split("").reverse().join(""));
} letters.slice(0, i + 1).split("").reverse().join("") returns letters from index i down to index 0 — exactly the reverse row shape. Great once you understand the nested-loop idea; keep the two-loop version for exams that ask you to show descending bounds.
Use prompt() when reading input. Set rows (fixed or from user) and base = "A".charCodeAt(0).
for (let i = 0; i < rows; i++) selects the starting letter index for the current line.
for (let code = base + i; code >= base; code--) prints each letter downward with line += String.fromCharCode(code).
console.log(line) ends the row so the next outer iteration starts fresh.
Total letters: 1+2+…+n = n(n+1)/2 — O(n²) time, O(1) extra memory.
rows = 5Trace each outer-loop index and see what the descending inner loop prints down to A.
Row index i | Inner code range | Printed row | Letters this row |
|---|---|---|---|
0 | A..A | A | 1 |
1 | B..A | BA | 2 |
2 | C..A | CBA | 3 |
3 | D..A | DCBA | 4 |
4 | E..A | EDCBA | 5 |
Total letter prints: 1 + 2 + 3 + 4 + 5 = 15 = 5×6/2.
Where this reverse triangle (and its descending inner loop) shows up beyond the homework prompt.
Clearest visual proof that a descending loop must use code >= base so the final letter A is included.
Example: change >= to > and watch A disappear.
Same growing row width — only inner direction changes from ascending to descending.
Example: side-by-side output of AB vs BA on row 2.
Practice character loops with step -1 and line += String.fromCharCode(code)/console.log(line) without complex math.
Example: accidentally use an ascending inner loop and get Program 1’s shape.
Swap to lowercase or digits once the descending letter loop works.
Example: print lowercase edcba with "A".charCodeAt(0) as base.
Triangular totals make O(n²) concrete for beginners.
Example: count printed letters for n = 10 → 55.
Pair the pattern with Number.isFinite checks and positive-row validation.
Example: reject rows <= 0 and re-prompt.
Pro Tip: when an interviewer asks for patterns, explain why the condition is code >= base — that detail separates a working reverse row from a missing A.
Why this reverse triangle earns a spot in beginner JavaScript pattern courses.
Wrong stop values show up immediately — rows missing A or printing extra codes.
Only loops and console output — no arrays or math libraries.
Flip inner direction to recover Program 1; compare with Program 3’s fixed-top rows and Program 5’s shrinking width.
Streaming output needs no storage beyond loop counters.
Pro Tip: learn the nested-loop version first; treat letters.slice(0, i + 1).split("").reverse().join("") as a polish shortcut afterward.
Small habits that keep alphabet-pattern code clean.
Use rows (or n) and keep i/j for row/column — or rename to row/col.
Avoid crashes when the user types letters instead of a number.
Only call console.log(line) after the inner loop finishes the row.
Prefer "A".charCodeAt(0) over hardcoded 65 — clearer intent and easier to switch to lowercase.
Trace rows = 3 on paper — confirm for (let code = base + i; code >= base; code--) includes A.
Pro Tip: if the output is a vertical list of single letters, you almost certainly put console.log(line) inside the inner loop.
Mistakes that commonly break reverse alphabet triangle patterns.
Each letter lands on its own line — you get a column, not a triangle.
→ Use line += String.fromCharCode(code) for letters; console.log(line) only after the inner loop.
Using base as the stop skips A; using base - 2 may print unwanted characters below A.
→ For this shape, keep for (let code = base + i; code >= base; code--) so A is included.
for (code = base; code <= base + i; code++) prints Program 1’s shape (AB, not BA).
→ Use step -1 and start at base + i, not at base.
Magic ASCII numbers work but obscure intent and break when switching to lowercase.
→ Always set base = "A".charCodeAt(0) and derive codes from base + i.
Non-numeric input yields NaN with bare parseInt(prompt()).
→ Check with Number.isFinite and clamp the range.
Omitting console.log(line) after the inner loop glues every letter onto one endless line.
→ Always end the row after the inner loop.
Check these inputs before calling the solution done.
Output is just A on one line.
Outer loop never runs — print nothing or show a message.
rows < 0Treat as invalid; re-prompt instead of silent empty output.
Output grows as n²/2 characters — fine for labs, noisy for huge n.
parseInt(prompt()) can yield NaN — validate with Number.isFinite first.
Same loops work with #, digits, or letters.
Try these variations to lock in the reverse pattern.
rows = 5base = "a".charCodeAt(0) with the same logica, ba, cba, …Number.isFinite until rows >= 1letters.slice(0, i + 1).split("").reverse().join("")for (let code = base + i; code >= base; code--) includes A because the condition keeps running while code >= base.rows > 0 for interactive programs; rows = 1 should print a single A.Quick Takeaway: outer loop picks the start letter, inner loop counts down to A with step -1, then break the line — that is the whole pattern.
| Program | Time | Extra space |
|---|---|---|
| Nested loops (Examples 1–2) | O(rows²) | O(1) |
letters.slice(0, i + 1).split("").reverse().join("") (Example 3) | O(rows²) | O(rows) per row string (temporary) |
The reverse alphabet triangle is a focused nested-loop exercise with lasting payoff: descending inner bounds, the inclusive code >= base stop, and O(n²) intuition. Master the classic two-loop version, then optionally shorten rows with letters.slice(0, i + 1).split("").reverse().join("").
Practice the three examples above, then continue to Program 5 for the decreasing-width pattern (ABCDE down to A).
Row i prints from String.fromCharCode("A".charCodeAt(0) + i) down to A — keep line += String.fromCharCode(code) for letters, console.log(line) for the break, and validate row counts when reading input.
for (let code = base + i; code >= base; code--) so every row ends at Abase = "A".charCodeAt(0) over hardcoded ASCII valuesrows ≥ 1 and clamp to 26 for A–Z demosfor (code = base; code <= base + i; code++))code > base instead of >= — that skips Aconsole.log(line) inside the inner letter loop65 instead of "A".charCodeAt(0)rows = 1 edge casePrint each row from the current letter down to A.
Row i counts down to A
Definitionfor (let i = 0; i < rows; i++) picks start
Step -1 down to A
CodeIncludes letter A
BoundsO(n²) time
AnalysisRow index i (0-based) logs letters from String.fromCharCode("A".charCodeAt(0) + i) down to A using for (let code = base + i; code >= base; code--). 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).
Shrink each row from ABCDE down to A — the decreasing alphabet pattern.
12 people found this page helpful