Shape Rule
Shrink width, keep sequence
Row 1 prints rows letters; each next row prints one fewer - down to 1.

Each row is shorter than the last, but letters stay in order across the whole shape: A B C D E, then F G H I, then J K L, M N, and O for five rows. This combines a shrinking outer loop with the running counter from Program 13 - unlike Program 5, letters never reset. Includes a live preview, worked JavaScript examples, edge cases, and complexity.
Shrink width, keep sequence
Row 1 prints rows letters; each next row prints one fewer - down to 1.
Never reset
code = "A".charCodeAt(0) lives outside the outer loop and advances across rows.
rowLen = rows; rowLen >= 1; rowLen--
for (let rowLen = rows; rowLen >= 1; rowLen--) picks how many letters this row prints.
Same line / next line
Letters use line += ch + " "; end each row with console.log(line).
1–6 rows
Pick a row count and draw the continuous decreasing triangle in the browser.
Complexity
Total letters = n(n+1)/2; extra memory stays O(1).
A continuous alphabet triangle with decreasing rows starts with the longest line and shortens by one letter each row - but the alphabet never restarts. Letters flow continuously: the last letter on one row is followed by the next letter on the next row.
In JavaScript you solve it with nested for loops, a decreasing outer bound rowLen = rows; rowLen >= 1; rowLen--, and a running code counter that increments after every letter.
It merges two ideas from earlier patterns: shrinking row width (Program 5) and a continuous counter (Program 13). Once both click, you can mix width rules with any ordered token stream.
One code walks A, B, C… across the whole triangle.
Outer loop prints rows, rows−1, …, 1 letters per row.
code += 1 belongs inside the inner loop, not after the row.
Program 5 resets to A each row; this one never resets.
In short: start code = "A".charCodeAt(0), loop row_len from rows down to 1, append row_len letters with line += String.fromCharCode(code) + " " then code++, and call console.log(line) after each row.
Given a positive integer rows, print a left-aligned triangle of consecutive alphabet letters where the first row has rows letters, each next row one fewer, and the sequence never resets.
// First 5 rows (with spaces)
// A B C D E
// F G H I
// J K L
// M N
// O | Item | Type | Description |
|---|---|---|
rows | int | Number of triangle lines. For A–Z only, keep rows(rows+1)/2 ≤ 26 (max 6 full rows = 21 letters). |
| Printed output | text | Left-aligned consecutive letters; spaces between letters on a row. |
code = "A".charCodeAt(0)
for row_len from rows down to 1:
line = ""
for each letter in this row:
line += String.fromCharCode(code) + " "
code++
console.log(line) | Approach | Idea | Best for |
|---|---|---|
Running code | Decreasing outer width + inner print/code += 1 | Learning and interviews |
row.join(" ") | Build a list per row, join with spaces | Clean output without trailing space |
| Reset-per-row style | See Program 5 (ABCDE, ABCD, …) | When each row starts from A |
| Goal | Pattern |
|---|---|
| Start the sequence | code = "A".charCodeAt(0) (outside outer loop) |
| Shrink row width | for (let rowLen = rows; rowLen >= 1; rowLen--) |
| Print next letter | line += String.fromCharCode(code) + " "; code++ |
| Clean row (no trailing space) | console.log(row.join(" ")) |
| End the row | console.log(line) |
| Growing continuous rows | See Program 13 (A, B C, D E F, …) |
Same tools - different width rule and reset policy.
grow rows
continuousWidth 1, 2, 3…; running counter - A, B C, D E F
shrink rows
reset AWidth n, n−1…; each row starts from A - ABCDE, ABCD
shrink rows
continuousWidth n, n−1…; running counter - A B C D E, F G H I
no resetDo not set code = "A".charCodeAt(0) inside the outer loop
Reach for a shrinking outer loop plus running counter when width and sequence rules differ.
Combine growing/shrinking width with reset vs continuous fill.
Practice rowLen = rows; rowLen >= 1; rowLen-- with immediate visual feedback.
Same idea works with numbers or any ordered token stream.
Next: alphabet rotation rows (ABCDE, BCDEA, …).
This is a console teaching pattern - not how you build modern app screens.
Key benefit: one program that proves you can mix any width rule with a continuous counter - a skill used far beyond alphabet demos.
Choose a row count between 1 and 6 and draw the continuous decreasing alphabet triangle in the browser (spaces between letters).
Three complete JavaScript programs - fixed five rows, prompt input, and a join-based variant without trailing spaces. Click View Output to reveal sample console results, or Try it Yourself to run in the browser editor.
Print five decreasing rows with a running character and spaces.
rows = 5Hard-coded height - ideal for first demos and screenshots.
const rows = 5;
let code = "A".charCodeAt(0);
for (let rowLen = rows; rowLen >= 1; rowLen--) {
let line = "";
for (let i = 0; i < rowLen; i++) {
line += String.fromCharCode(code) + " ";
code++;
}
console.log(line);
} code starts at "A".charCodeAt(0) and never resets. The outer loop walks rowLen from 5 down to 1; the inner loop appends that many consecutive letters. code++ after each letter keeps the sequence continuous.
Let the user choose the height at runtime.
Read rows and clamp to 1–6 for A–Z demos. Validate parseInt(prompt()) with Number.isFinite in real apps.
let rows = parseInt(prompt("Enter number of rows (max 6):"), 10);
if (!Number.isFinite(rows)) {
console.log("Please enter a whole number.");
} else {
rows = Math.max(1, Math.min(rows, 6));
let code = "A".charCodeAt(0);
for (let rowLen = rows; rowLen >= 1; rowLen--) {
let line = "";
for (let i = 0; i < rowLen; i++) {
line += String.fromCharCode(code) + " ";
code++;
}
console.log(line);
}
} Same running-code core as Example 1; only the outer bound and clamp change. Six rows need 21 letters (A–U) - still inside A–Z.
Build each row as an array and join - no trailing space.
row.join(" ") VariantCollect letters in an array, then join with spaces for tidy rows.
const rows = 5;
let code = "A".charCodeAt(0);
for (let rowLen = rows; rowLen >= 1; rowLen--) {
const row = [];
for (let i = 0; i < rowLen; i++) {
row.push(String.fromCharCode(code));
code++;
}
console.log(row.join(" "));
} The code++ logic is identical; only formatting changes. row.join(" ") inserts spaces between letters without a trailing space at the end of the line.
Start code = "A".charCodeAt(0) before the outer loop. Optionally read and clamp rows.
for (let rowLen = rows; rowLen >= 1; rowLen--) decides how many letters this row prints - longest first.
Print String.fromCharCode(code), optional space, then code += 1 so the next cell gets the next letter.
console.log(line) ends the row; code keeps its value for the next (shorter) row.
Total letters: 1+2+…+n = n(n+1)/2 — O(n²) time, O(1) extra memory.
rows = 5Trace each outer-loop value of row_len and watch how code advances across the whole triangle.
row_len | code before row | Printed row | code after row |
|---|---|---|---|
5 | 'A' | A B C D E | 'F' |
4 | 'F' | F G H I | 'J' |
3 | 'J' | J K L | 'M' |
2 | 'M' | M N | 'O' |
1 | 'O' | O | 'P' |
Total letter prints: 5 + 4 + 3 + 2 + 1 = 15 = 5×6/2 (A through O).
Where this tiny pattern (and its running counter plus shrinking width) shows up beyond the homework prompt.
Merge Program 13’s counter with Program 5’s decreasing width.
Example: side-by-side ABCDE/ABCD vs A B C D E/F G H I.
Reinforce rowLen = rows; rowLen >= 1; rowLen-- with a continuous fill check.
Example: trace row_len 5, 4, 3 on paper before coding.
Swap code for an integer counter to print 1 2 3 4 5 / 6 7 8 9 / …
Example: start n = 1 and print/increment the same way.
Use join, commas, or no spaces without changing the sequence logic.
Example: Example 3 uses row.join(" ") for clean rows.
Triangular totals make O(n²) concrete for beginners.
Example: 5 rows → 15 letters (A–O).
Pair the pattern with a “stop at Z” or clamp policy.
Example: cap rows at 6 so 21 letters stay in A–Z.
Pro Tip: say “outer loop shrinks width; one counter walks the alphabet” before coding - that story prevents resetting code each row.
Why this pattern earns a spot after the growing and reset-per-row triangles.
Practices both reverse outer bounds and continuous state in a single program.
Only loops, one extra char, and console output.
Swap letters for digits, flip to growing rows, or use join formatting with tiny edits.
Streaming output needs no storage beyond loop counters and code.
Pro Tip: keep code outside the outer loop; resetting it each row accidentally recreates Program 5’s shape with a different letter rule.
Small habits that keep continuous decreasing-pattern code clean.
Use code or nextLetter for the sequence - keep row_len for width.
parseInt(prompt(), 10) in Number.isFiniteAvoid crashes when the user types letters instead of a number.
Put code += 1 inside the inner loop, after printing.
Six rows use 21 letters; cap at 6 when you want A–Z only.
Trace rows = 3 (A B C / D E / F) on paper before coding larger demos.
Pro Tip: if every row starts with A, you almost certainly reset code inside the outer loop - that is Program 5, not this pattern.
Mistakes that commonly break continuous decreasing alphabet patterns.
code Each RowSetting code = "A".charCodeAt(0) inside the outer loop recreates Program 5’s reset-style triangle.
→ Declare and initialize code once, before the outer loop.
1..rows prints Program 13’s growing continuous triangle, not this one.
→ Use rowLen = rows; rowLen >= 1; rowLen-- for decreasing row lengths.
Each letter lands on its own line - you get a column, not a triangle.
→ Use line += ch + " " for letters; console.log(line) only after the inner loop.
Non-numeric input yields NaN with bare parseInt(prompt()).
→ Validate parseInt(prompt()) with Number.isFinite and validate range.
Large rows walk past 'Z' into non-letter characters.
→ Cap rows at 6 for A–Z demos or stop when code > "Z".charCodeAt(0).
Check these inputs before calling the solution done.
Output is just A on one line.
Treat as invalid; re-prompt instead of silent empty output.
21 letters (A–U). Last row is a single letter U.
More than 21 letters needed - clamp or define wrap/stop policy.
Use Number.isFinite before clamping rows.
Same loops work with code = "a".charCodeAt(0).
Try these variations to lock in the pattern.
coden(n+1)/2 - same as Program 13, hence O(n²) time.code outside the outer loop; use rowLen = rows; rowLen >= 1; rowLen-- for decreasing widths.row.join(" ") avoids trailing spaces; the letter sequence stays identical.Quick Takeaway: shrinking outer loop picks the width, running code supplies consecutive letters, then break the line - that is the whole pattern.
| Program | Time | Extra space |
|---|---|---|
| Nested loops (Examples 1–2) | O(rows²) | O(1) |
| join variant (Example 3) | O(rows²) | O(row_len) per row for the list |
The continuous decreasing alphabet triangle merges two skills: a shrinking outer loop and a running counter that never resets. Master the core nested-loop version, then try the join variant for cleaner rows.
Practice the three examples above, then continue to Program 26’s alphabet rotation pattern.
Keep code outside the outer loop, use rowLen = rows; rowLen >= 1; rowLen--, increment per cell, and clamp rows for A–Z demos.
code once before the outer loopfor (let rowLen = rows; rowLen >= 1; rowLen--)code inside the inner loop after each lettercode = "A".charCodeAt(0) on every outer iteration1..rows unless you want Program 13’s shapeconsole.log(line) inside the inner letter loopPrint the continuous decreasing triangle the beginner-friendly way.
Continuous letters, shrinking width
DefinitionNever reset between rows
CoderowLen = rows; rowLen >= 1; rowLen--
CodeEnds each row
I/OO(n²) time
AnalysisOne running counter prints letters continuously while row length shrinks: 5 letters, then 4, 3, 2, 1. Total letters for n rows is still n(n+1)/2 - compare Program 13 (growing rows) and Program 5 (decreasing rows but letters reset each line).
Next up: alphabet rotation rows (ABCDE, BCDEA, CDEBA, …) with cyclic letter shifts.
12 people found this page helpful