Append letters without a newline, then end the row once.
Try it
Live Preview
Change the row count and the reverse alphabet triangle updates instantly — including the top letter and triangular total.
Whole numbers from 1 to 10. Size 5 starts at E. Tap a chip or type a value — the preview redraws as you go.
Live result5 rows · top E · 15 letters
E
ED
EDC
EDCB
EDCBA
Trace
Worked Walkthrough — rows = 4
With 4 rows, top = D. Trace each outer-loop value of i and the letters appended on that row.
i
Codes
Printed row
Letters
1
D
D
1
2
D..C
DC
2
3
D..B
DCB
3
4
D..A
DCBA
4
Total letter characters: 1 + 2 + 3 + 4 = 10 = 4×5/2. That triangular sum is why time is O(n²).
Code
JavaScript Programs
Three complete programs: fixed rows, prompt input, and a slice shortcut. 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 — ideal for first demos and screenshots.
JavaScript
const rows = 5;
const top = "A".charCodeAt(0) + rows - 1;
for (let i = 1; i <= rows; i++) {
let line = "";
for (let code = top; code > top - i; code--) {
line += String.fromCharCode(code);
}
console.log(line);
}
1. Set height and top code.rows = 5; top becomes the code of E.
2. Outer loop picks the row.i runs from 1 to rows. Start each row with an empty line.
3. Inner loop counts down.code runs from top down through i letters, so row i gets exactly i characters.
4. Break the line.console.log(line) after the inner loop prints the row and starts the next one.
When i = 1 you get E; when i = 3 you get EDC; and so on up to EDCBA.
Example 2 — User Input Version
Read the row count at runtime with prompt. Validate with parseInt and clamp to 26 for A–Z demos.
JavaScript
let rows = parseInt(prompt("Enter the number of rows:"), 10);
if (!Number.isFinite(rows) || rows < 1) {
console.log("Please enter a whole number of rows >= 1.");
} else {
if (rows > 26) rows = 26;
const top = "A".charCodeAt(0) + rows - 1;
for (let i = 1; i <= rows; i++) {
let line = "";
for (let code = top; code > top - i; code--) {
line += String.fromCharCode(code);
}
console.log(line);
}
}
Break the row: call console.log(line) only after the inner loop.
Complexity:O(n²) from the triangular letter count n(n+1)/2.
One line: for each row length i, append i letters counting down from top, then console.log.
Frequently Asked Questions
The outer loop picks row length i from 1 to rows. The inner loop runs for (let code = top; code > top - i; code--) to append top down through i letters — so row 1 is E, row 2 is ED, and so on.
The inner loop always starts at top (E when rows = 5). Only how many letters print changes with i — that is what grows the reverse triangle.
line += String.fromCharCode(code) stays on the same row. console.log(line) ends the row after the inner loop finishes.
Use Program 1: loop upward from A with for (let code = start; code < start + i; code++). This page is the descending mirror of that forward triangle.
O(n²) where n is the number of rows. Total printed characters equal 1+2+…+n = n(n+1)/2.
Use parseInt(prompt(...), 10), check Number.isFinite(rows), and clamp between 1 and 26 so letter codes stay within A–Z.
code-- counts down. The loop stops when code is no longer greater than top - i, so you get exactly i values: top, top-1, …, top-i+1.
Yes. Build a descending string such as EDCBA and console.log(descending.slice(0, i)) for row length i. Nested loops are better for learning; slicing is a handy shortcut later.
🤔
Did you know?
Row i prints i letters from the top letter down. For 5 rows the output is E, ED, EDC, EDCB, EDCBA — the descending mirror of Program 1. Total letters = n(n+1)/2.