Shape Rule
Growing forward rows
Row k prints k letters ending at the fixed top.

Print an alphabet triangle where each row starts one letter earlier, but letters still run forward to a fixed top — E, DE, CDE, BCDE, ABCDE. Mixes ideas from Program 1 (forward run) and Program 2 (moving start). Includes a live preview, worked JavaScript examples, edge cases, and complexity.
Growing forward rows
Row k prints k letters ending at the fixed top.
Row start letter
for (let code = top; code >= base; code--) picks the first letter.
Forward to top
j starts at i and prints up to top.
Always top
Every row ends at E (or your chosen top).
1–10 rows
Pick a height and draw the triangle instantly.
Complexity
Triangular letter count: n(n+1)/2 writes.
An alphabet triangle with reverse starting letter grows like Programs 1 and 2, but the first letter of each row moves backward while letters along the row still increase forward to a fixed top.
In JavaScript you solve it with nested for loops and charCodeAt/fromCharCode: the outer loop walks the start code from top down to A, and the inner loop appends from that start up to top.
It trains mixing a descending outer bound with an ascending inner loop — a common combo in aligned suffixes, diagonals, and later pyramid patterns.
1, 2, 3, … letters per row.
Outer loop: E, D, C, …
Inner loop uses for (let j = code; j <= top; j++).
Every row ends at top.
In short: for each start letter i from top down to A, append i..top, then call console.log(line).
Given a row count n (or fixed A–E), print a left-aligned triangle of forward alphabet suffixes ending at a fixed top.
// Five rows (top = E)
# E
# DE
# CDE
# BCDE
# ABCDE | Item | Type | Description |
|---|---|---|
rows / top | int / char | Number of rows, or top letter where top = "A".charCodeAt(0) + rows - 1. |
| Printed output | text | Growing forward suffixes ending at top on every row. |
top = "A".charCodeAt(0) + rows - 1
for i from top down to base: // start letter
line = ""
for j from i up to top: // forward run
line += String.fromCharCode(j)
console.log(line) | Approach | Idea | Best for |
|---|---|---|
| Outer down, inner up | Start moves back; letters run forward | Matching this classic sample |
| Substring of A..top | Take trailing slice of length k | Shortcut after you understand the loops |
| Goal | Pattern |
|---|---|
| Top letter | top = "A".charCodeAt(0) + rows - 1 |
| Outer (start letter) | for (let code = top; code >= base; code--) |
| Inner (append) | for (let j = code; j <= top; j++) line += String.fromCharCode(j) |
| End the row | console.log(line) |
| Descending along row | See Program 2 |
| Lowercase | Use 'a' as the base instead of 'A' |
Same growing triangle - different start and letter direction.
A..iAlways starts at A; end grows
top..iAlways starts at top; letters descend
i..topStart moves back; letters ascend
breakEnds the row after i..top finishes
Reach for this when teaching a descending start bound with a forward letter run.
Keep the triangle; mix reverse start with forward letters.
Practice suffixes that always end at the same letter.
Next flips direction again: A, BA, CBA, …
Mix a descending outer code-- loop with an ascending inner j++ loop.
This is a console teaching pattern — not how you build modern app screens.
Key benefit: one descending start plus a forward inner loop is the cleanest way to keep a fixed right edge while rows grow.
Choose 1–10 rows and draw the reverse-starting-letter alphabet triangle in the browser.
Three complete JavaScript programs - fixed A–E, user-chosen row count, and a spaced-letter variant. Click View Output to reveal sample console results, or Try it Yourself to run in the browser editor.
Print five rows with a moving start and a forward letter run.
EOuter loop chooses the first letter on the row; inner loop appends forward up to 'E'.
const top = "E".charCodeAt(0);
const base = "A".charCodeAt(0);
for (let code = top; code >= base; code--) {
let line = "";
for (let j = code; j <= top; j++) {
line += String.fromCharCode(j);
}
console.log(line);
} When code is 'C', the inner loop appends C, D, E → CDE. When code is 'A', it appends the full forward run ABCDE.
Let the user choose how many rows to print.
Read the number of rows and compute top = "A".charCodeAt(0) + rows - 1. Validate parseInt(prompt()) with Number.isFinite and clamp rows in real apps.
let rows = parseInt(prompt("Enter the number of rows:"), 10);
if (!Number.isFinite(rows)) {
console.log("Please enter a whole number.");
} else {
rows = Math.max(1, Math.min(rows, 26));
const base = "A".charCodeAt(0);
const top = base + rows - 1;
for (let code = top; code >= base; code--) {
let line = "";
for (let j = code; j <= top; j++) {
line += String.fromCharCode(j);
}
console.log(line);
}
} For 4 rows, top becomes 'D'. Cap rows at 26 so top stays within A–Z.
Same triangle with spaces between letters.
Append a trailing space after each letter so columns are easier to scan.
const top = "E".charCodeAt(0);
const base = "A".charCodeAt(0);
for (let code = top; code >= base; code--) {
let line = "";
for (let j = code; j <= top; j++) {
line += String.fromCharCode(j) + " ";
}
console.log(line);
} Same start/forward logic; only the append format adds a trailing space after each letter.
i runs from top down to 'A'. That makes each row start one letter earlier.
For each row, j runs from i up to top. So row i prints i, i+1, ..., top.
console.log(line) ends the row and moves to the next line.
Because the inner loop always stops at top, every row ends on the same letter while the left side grows.
Total printed characters are 1+2+…+n, so time complexity is O(n²).
Trace each start letter and the resulting forward suffix.
i (start) | Inner range | Printed row |
|---|---|---|
E | E..E | E |
D | D..E | DE |
C | C..E | CDE |
B | B..E | BCDE |
A | A..E | ABCDE |
Row lengths are 1, 2, 3, 4, 5. The right edge is always E.
Where this reverse-start forward triangle shows up beyond the homework prompt.
Clearest demo of a descending outer loop with a forward inner range in one program.
Example: flip the inner loop to count down and land on Program 2.
Practice suffixes that always end at the same letter.
Example: change top to H and watch every row end at H.
Contrast with Programs 1 and 2 side by side.
Example: same 5 rows, three different letter stories.
Add separators without changing loop structure (Example 3).
Example: print j + " " for easier scanning.
Triangular counts make O(n²) easy to see.
Example: 5 rows print 15 letters total.
Next prints reverse-order rows: A, BA, CBA, …
Example: continue to Program 4.
Pro Tip: say “start moves back, letters run forward to top” before coding - that story prevents accidentally writing Program 2’s j--.
Why this pattern earns a spot between Programs 2 and 4.
A wrong inner direction shows up as Program 2’s shape.
Outer descends; inner ascends — both in one file.
Change rows / top and the whole triangle grows.
Fixed end letter makes the suffix idea easy to explain.
Pro Tip: learn the compact line += String.fromCharCode(j) version first; add spaces only when you need readable columns.
Small habits that keep reverse-start triangles clean.
Use j++ from i to top — not j--.
Use top = "A".charCodeAt(0) + rows - 1 so scaling stays automatic.
Keep top within A–Z for demos.
parseInt(prompt(), 10) in Number.isFiniteValidate row input instead of blind parseInt(prompt(), 10).
Calling it inside the letter loop breaks the triangle into a column.
Pro Tip: if you see E, ED, EDC, the inner loop is decrementing — that is Program 2, not this page.
Mistakes that commonly break reverse-starting-letter triangles.
Produces Program 2’s descending rows (E, ED, EDC).
→ Append with j++ from code to top — not a descending inner loop.
Gives Program 1’s prefixes instead of suffixes to top.
→ Start j at i, not at 'A'.
Large rows values can walk past Z.
→ Clamp rows to 1–26 for A–Z demos.
parseInt(prompt())Empty or non-numeric input throws.
→ Use Number.isFinite and clamp rows to 1..26.
Prints one letter per line instead of a triangle.
→ Call console.log(line) only after the letter loop finishes.
Check these inputs before calling the solution done.
Output is just A.
E through ABCDE with right edge E.
D, CD, BCD, ABCD (Example 2).
Clamp or define a wrap/error policy.
Validate with Number.isFinite.
Use 'a' as the base instead of 'A'.
Try these variations to lock in the pattern.
j-- from topj + " " (Example 3)i walks E, D, C, … while the right edge stays fixed.j++ from code to top — not a descending inner loop.n(n+1)/2.Quick Takeaway: move the start letter backward, append forward to a fixed top, then call console.log(line).
| Program | Time | Extra space |
|---|---|---|
| Inline / input (Examples 1–2) | O(n²) | O(1) |
| Spaced letters (Example 3) | O(n²) | O(1) |
For n rows you print 1+2+…+n = n(n+1)/2 letters, so total work is O(n²).
The reverse-starting-letter alphabet triangle keeps a fixed right edge while the left side grows: start letter moves from top down to A, and each row prints forward to top. Master the classic E…ABCDE sample, then try user input and the spaced rewrite.
Practice the three examples above, then continue to Program 4’s reverse-order alphabet triangle (A, BA, CBA, …).
Outer code from top to A, inner j from code to top, then console.log(line).
i and increment to toptop from the row countNumber.isFiniteA every row (that is Program 1)console.log(line) inside the letter loopPrint the reverse-starting-letter alphabet triangle the beginner-friendly way.
Start back, run forward
Definitionj from i to top
CodeAlways top
ShapeEnds each row
I/OO(n²) time
AnalysisThis triangle changes only the starting letter of each row (E, D, C, …), while letters along the row still increase forward. In the 5-row example, every row ends at E, producing E, DE, CDE, BCDE, ABCDE.
Next up: reverse-order alphabet triangles where each row starts later and prints backward to A.
12 people found this page helpful