Continuous Alphabet Triangle (Decreasing Rows) in JavaScript

Beginner
⏱️ 8 min read
📚 Updated: Aug 2026
🎯 3 Code Examples
🚀 Live Preview
Nested Loops

What You’ll Learn

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.

Shape Rule

Shrink width, keep sequence

Row 1 prints rows letters; each next row prints one fewer - down to 1.

Running Char

Never reset

code = "A".charCodeAt(0) lives outside the outer loop and advances across rows.

Decreasing Outer Loop

rowLen = rows; rowLen >= 1; rowLen--

for (let rowLen = rows; rowLen >= 1; rowLen--) picks how many letters this row prints.

line += vs console.log

Same line / next line

Letters use line += ch + " "; end each row with console.log(line).

Live Preview

1–6 rows

Pick a row count and draw the continuous decreasing triangle in the browser.

O(n²)

Complexity

Total letters = n(n+1)/2; extra memory stays O(1).

Introduction

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.

Why it matters?

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.

Key Highlights

Continuous Letters

One code walks A, B, C… across the whole triangle.

Width Shrinks

Outer loop prints rows, rows−1, …, 1 letters per row.

Increment Per Cell

code += 1 belongs inside the inner loop, not after the row.

Not Program 5

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.

📝 Problem & Approach

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.

JavaScript
// First 5 rows (with spaces)
// A B C D E
// F G H I
// J K L
// M N
// O

Inputs & Outputs

ItemTypeDescription
rowsintNumber of triangle lines. For A–Z only, keep rows(rows+1)/2 ≤ 26 (max 6 full rows = 21 letters).
Printed outputtextLeft-aligned consecutive letters; spaces between letters on a row.

Minimal workflow

Pseudocode
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 comparison

ApproachIdeaBest for
Running codeDecreasing outer width + inner print/code += 1Learning and interviews
row.join(" ")Build a list per row, join with spacesClean output without trailing space
Reset-per-row styleSee Program 5 (ABCDE, ABCD, …)When each row starts from A

⚡ Quick Reference

GoalPattern
Start the sequencecode = "A".charCodeAt(0) (outside outer loop)
Shrink row widthfor (let rowLen = rows; rowLen >= 1; rowLen--)
Print next letterline += String.fromCharCode(code) + " "; code++
Clean row (no trailing space)console.log(row.join(" "))
End the rowconsole.log(line)
Growing continuous rowsSee Program 13 (A, B C, D E F, …)

📋 Program 13 vs Program 5 vs This Pattern

Same tools - different width rule and reset policy.

Program 13
grow rows
continuous

Width 1, 2, 3…; running counter - A, B C, D E F

Program 5
shrink rows
reset A

Width n, n−1…; each row starts from A - ABCDE, ABCD

Program 25 (this)
shrink rows
continuous

Width n, n−1…; running counter - A B C D E, F G H I

Learning tip
no reset

Do not set code = "A".charCodeAt(0) inside the outer loop

Context

When This Pattern Shows Up

Reach for a shrinking outer loop plus running counter when width and sequence rules differ.

  1. After Program 13 and 5

    Combine growing/shrinking width with reset vs continuous fill.

  2. Reverse outer bounds

    Practice rowLen = rows; rowLen >= 1; rowLen-- with immediate visual feedback.

  3. Digit / token fills

    Same idea works with numbers or any ordered token stream.

  4. Gateway to Program 26

    Next: alphabet rotation rows (ABCDE, BCDEA, …).

  5. Not a UI layout tool

    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.

🔮 Live Preview

Choose a row count between 1 and 6 and draw the continuous decreasing alphabet triangle in the browser (spaces between letters).

Try 5 (through O) or 3 (A B C / D E / F). Six rows use 21 letters (A–U).

Live result
Press "Draw pattern".

Examples Gallery

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.

📚 Getting Started

Print five decreasing rows with a running character and spaces.

Example 1 — Fixed rows = 5

Hard-coded height - ideal for first demos and screenshots.

JavaScript
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);
}
Try it Yourself

How It Works

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.

📈 Practical Variant

Let the user choose the height at runtime.

Example 2 — User Input Version

Read rows and clamp to 1–6 for A–Z demos. Validate parseInt(prompt()) with Number.isFinite in real apps.

JavaScript
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);
  }
}
Try it Yourself

How It Works

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.

⚡ Clean Output Style

Build each row as an array and join - no trailing space.

Example 3 — row.join(" ") Variant

Collect letters in an array, then join with spaces for tidy rows.

JavaScript
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(" "));
}
Try it Yourself

How It Works

The code++ logic is identical; only formatting changes. row.join(" ") inserts spaces between letters without a trailing space at the end of the line.

🧠 How the Algorithm Prints Rows

1

Set up

Start code = "A".charCodeAt(0) before the outer loop. Optionally read and clamp rows.

Setup
2

Outer loop (width)

for (let rowLen = rows; rowLen >= 1; rowLen--) decides how many letters this row prints - longest first.

n..1
3

Inner loop (cells)

Print String.fromCharCode(code), optional space, then code += 1 so the next cell gets the next letter.

code += 1
4

New line

console.log(line) ends the row; code keeps its value for the next (shorter) row.

Break
=

Triangle complete

Total letters: 1+2+…+n = n(n+1)/2O(n²) time, O(1) extra memory.

🔎 Worked Walkthrough — rows = 5

Trace each outer-loop value of row_len and watch how code advances across the whole triangle.

row_lencode before rowPrinted rowcode 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).

Use Cases

Where this tiny pattern (and its running counter plus shrinking width) shows up beyond the homework prompt.

1. Combine Two Ideas

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.

2. Reverse Range Practice

Reinforce rowLen = rows; rowLen >= 1; rowLen-- with a continuous fill check.

Example: trace row_len 5, 4, 3 on paper before coding.

3. Number Triangles

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.

4. Formatting Variants

Use join, commas, or no spaces without changing the sequence logic.

Example: Example 3 uses row.join(" ") for clean rows.

5. Complexity Intuition

Triangular totals make O(n²) concrete for beginners.

Example: 5 rows → 15 letters (A–O).

6. Alphabet Bounds Labs

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.

Advantages

Why this pattern earns a spot after the growing and reset-per-row triangles.

  1. 1. Two Skills in One

    Practices both reverse outer bounds and continuous state in a single program.

  2. 2. Minimal Concepts

    Only loops, one extra char, and console output.

  3. 3. Easy to Adapt

    Swap letters for digits, flip to growing rows, or use join formatting with tiny edits.

  4. 4. O(1) Extra Memory

    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.

Usage Tips

Small habits that keep continuous decreasing-pattern code clean.

  1. 1. Name the Runner

    Use code or nextLetter for the sequence - keep row_len for width.

  2. 2. Wrap parseInt(prompt(), 10) in Number.isFinite

    Avoid crashes when the user types letters instead of a number.

  3. 3. Increment Per Cell

    Put code += 1 inside the inner loop, after printing.

  4. 4. Clamp for A–Z Demos

    Six rows use 21 letters; cap at 6 when you want A–Z only.

  5. 5. Dry-Run One Small n

    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.

Common Pitfalls

Mistakes that commonly break continuous decreasing alphabet patterns.

  1. 1. Resetting code Each Row

    Setting code = "A".charCodeAt(0) inside the outer loop recreates Program 5’s reset-style triangle.

    → Declare and initialize code once, before the outer loop.

  2. 2. Using Growing Outer Loop

    1..rows prints Program 13’s growing continuous triangle, not this one.

    → Use rowLen = rows; rowLen >= 1; rowLen-- for decreasing row lengths.

  3. 3. console.log Inside the Inner Loop

    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.

  4. 4. Blind parseInt(prompt())

    Non-numeric input yields NaN with bare parseInt(prompt()).

    → Validate parseInt(prompt()) with Number.isFinite and validate range.

  5. 5. Ignoring the Z Boundary

    Large rows walk past 'Z' into non-letter characters.

    → Cap rows at 6 for A–Z demos or stop when code > "Z".charCodeAt(0).

Edge Cases

Check these inputs before calling the solution done.

rows = 1

Single letter

Output is just A on one line.

rows = 0

Empty pattern

Treat as invalid; re-prompt instead of silent empty output.

rows = 6

Max A–Z demo

21 letters (A–U). Last row is a single letter U.

rows > 6

Past Z

More than 21 letters needed - clamp or define wrap/stop policy.

Bad input

Non-numeric input

Use Number.isFinite before clamping rows.

Case

Lowercase variant

Same loops work with code = "a".charCodeAt(0).

🎯 Practice Problems

Try these variations to lock in the pattern.

1. Compare with Program 13

  • Growing width vs shrinking width
  • Both use continuous code
  • See Program 13

2. Compare with Program 5

  • Both shrink row width
  • Reset A vs continuous counter
  • See Program 5

3. Number version

  • Print 1 2 3 4 5 / 6 7 8 9 / …
  • Same loops, int counter

4. Rotation next

  • Continue to Program 26
  • Rows rotate: ABCDE, BCDEA, …

Notes

  • Triangular count. Total letters for n rows is n(n+1)/2 - same as Program 13, hence O(n²) time.
  • Keep code outside the outer loop; use rowLen = rows; rowLen >= 1; rowLen-- for decreasing widths.
  • row.join(" ") avoids trailing spaces; the letter sequence stays identical.
  • Clamp to 6 rows for A–Z demos (21 letters = A through U).

Quick Takeaway: shrinking outer loop picks the width, running code supplies consecutive letters, then break the line - that is the whole pattern.

⏱️ Time and Space Complexity

ProgramTimeExtra space
Nested loops (Examples 1–2)O(rows²)O(1)
join variant (Example 3)O(rows²)O(row_len) per row for the list
Wrap Up

🎉 Conclusion

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.

💡 Best Practices

✅ Do

  • Initialize code once before the outer loop
  • Use for (let rowLen = rows; rowLen >= 1; rowLen--)
  • Increment code inside the inner loop after each letter
  • Clamp rows to 1–6 for A–Z demos
  • State O(n²) time and the triangular letter count when asked

❌ Don’t

  • Reset code = "A".charCodeAt(0) on every outer iteration
  • Use 1..rows unless you want Program 13’s shape
  • Call console.log(line) inside the inner letter loop
  • Ignore the Z boundary for large row counts
  • Confuse this with Program 5’s reset-per-row rule

Key Takeaways

Knowledge Unlocked

Five things to remember about this alphabet pattern

Print the continuous decreasing triangle the beginner-friendly way.

5
Core concepts
A+ 02

Running char

Never reset between rows

Code
n..1 03

Outer loop

rowLen = rows; rowLen >= 1; rowLen--

Code
04

console.log

Ends each row

I/O
O 05

Complexity

O(n²) time

Analysis

❓ Frequently Asked Questions

Because code is initialized once before the outer loop and incremented after every printed character. The counter never resets, so letters stay consecutive across the whole triangle.
Program 13 grows row width (1, 2, 3, ... letters). This pattern shrinks width (n, n-1, ..., 1) while using the same running counter - A B C D E then F G H I, not A then B C.
Program 5 also uses decreasing row lengths but resets to A each row (ABCDE, ABCD, ABC, ...). Here letters continue: A B C D E, F G H I, J K L, M N, O.
That yields rows, rows-1, ..., 1 - exactly how many letters each row needs, longest first. Program 13 uses 1..rows for the opposite (growing) shape.
line += String.fromCharCode(code) + ' ' stays on the same row for each letter. console.log(line) ends the current row after the inner loop finishes.
1+2+...+n = n(n+1)/2. For 5 rows that is 15 letters (A through O).
O(n^2) where n is the number of rows. Total printed letters equal n(n+1)/2.
Use parseInt(prompt(), 10) and check Number.isFinite, then clamp rows between 1 and 6 so n(n+1)/2 stays within A-Z for demos.

Did you Know? 🔊

One 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).

Continue to Alphabet Pattern 26

Next up: alphabet rotation rows (ABCDE, BCDEA, CDEBA, …) with cyclic letter shifts.

Program 26 tutorial →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

12 people found this page helpful