Alphabet Rotation Pattern (Cyclic Wrap-Around Rows) in JavaScript

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

What You’ll Learn

Each row is a fixed width of rows letters, but the start letter shifts forward every line: ABCDE, BCDEA, CDEBA, DECBA, EDCBA for five rows. Two inner loops per row - forward to the top letter, then wrap down to A - teach cyclic rotation without string tricks. Compare with Program 1 (growing rows, no wrap). Includes a live preview, worked JavaScript examples, edge cases, and complexity.

Rotation Rule

Shift start, fixed width

Every row prints exactly rows letters; the first letter moves one step forward each row.

Forward Loop

Start → top

for (let j = i; j <= top; j++) appends from the row start up to the top letter.

Wrap Loop

Previous → A

for (let k = i - 1; k >= base; k--) fills remaining slots wrapping back to A.

charCodeAt / fromCharCode

Letter codes

base = "A".charCodeAt(0) and top = base + rows - 1 bound the alphabet window.

Live Preview

1–26 rows

Pick a row count and draw the rotation pattern in the browser instantly.

O(n²)

Complexity

n rows × n letters per row = total characters; extra memory stays O(1).

Introduction

An alphabet rotation pattern prints fixed-width rows where each line starts one letter later than the row above. After reaching the top letter, the row wraps back down to A to fill the remaining slots - a cyclic shift you may know from string rotation.

In JavaScript you solve it with an outer loop over start letters, two inner loops (forward then wrap), and charCodeAt/fromCharCode - or a one-line slice shortcut once the idea clicks.

Why it matters?

It teaches cyclic wrap-around with loops before you reach string slicing. The same rotation idea appears in circular buffers, Caesar ciphers, and queue rotation - all from two tiny inner loops.

Key Highlights

Fixed Width

Every row prints exactly rows letters - unlike Program 1’s growing triangle.

Shifted Start

Outer loop walks start letters from A through the top letter.

Wrap-Down Fill

Second inner loop prints from the previous letter down to A.

Not Program 1

Program 1 restarts at A each row with no wrap - A, AB, ABC.

In short: set base = "A".charCodeAt(0) and top = base + rows - 1, loop i from A to the top letter, append forward with one inner loop, wrap down with a second, then console.log(line) for the newline.

📝 Problem & Approach

Given a positive integer rows, print rows lines of exactly rows uppercase letters each. Row 1 starts at A and runs forward to the top letter; each next row starts one letter later and wraps back to A after the top.

JavaScript
// First 5 rows
// ABCDE
// BCDEA
// CDEBA
// DECBA
// EDCBA

Inputs & Outputs

ItemTypeDescription
rowsintNumber of rows and width of each row. Clamp to 1–26 for A–Z demos.
Printed outputtextFixed-width uppercase rows with cyclic wrap - no spaces between letters.

Minimal workflow

Pseudocode
base = "A".charCodeAt(0)
top = base + rows - 1
for i from base to top:
    line = ""
    append letters i..top (forward)
    append letters (i-1)..base (wrap, descending)
    console.log(line)

Approach comparison

ApproachIdeaBest for
Two inner loopsForward j = i..top + wrap k = (i-1)..baseLearning charCodeAt/fromCharCode and loop bounds
Slice rotationletters.slice(i) + [...letters.slice(0, i)].reverse().join("")Compact production code
Program 1 styleSee Program 1 (A, AB, ABC, …)Growing rows, no wrap-around

⚡ Quick Reference

GoalPattern
Bound the alphabetbase = "A".charCodeAt(0); top = base + rows - 1
Outer loop (start letter)for (let i = base; i <= top; i++)
Forward partfor (let j = i; j <= top; j++) line += String.fromCharCode(j)
Wrap partfor (let k = i - 1; k >= base; k--) line += String.fromCharCode(k)
End the rowconsole.log(line)
Slice shortcutconsole.log(letters.slice(i) + [...letters.slice(0, i)].reverse().join(""))

📋 Forward Loop vs Wrap Loop vs Slice Shortcut

Three ways to build the same rotation rows - pick based on what you are learning.

Forward loop
j = i; j <= top; j++
i..E

Appends from the row start letter up to the top - ABCDE starts with all five forward.

Wrap loop
k = i-1; k >= base; k--
..A

Fills remaining slots wrapping down - BCDEA adds A after BCDE.

Slice shortcut
letters.slice(i)
+ reverse(prefix)

One expression per row - same output, less loop bookkeeping.

Program 1 contrast
reset A
no wrap

Program 1 grows rows from A - A, AB, ABC - with no cyclic fill.

Context

When This Pattern Shows Up

Reach for rotation loops when each row is fixed width but the starting token shifts cyclically.

  1. After Program 1

    Program 1 grows from A with no wrap - this keeps width fixed and rotates the start.

  2. Two inner loops

    Practice forward and descending ranges on the same row before using slices.

  3. String rotation prep

    The slice form letters.slice(i) + [...letters.slice(0, i)].reverse().join("") matches the forward + reversed-prefix loops.

  4. Gateway to Program 27

    Next pattern in the alphabet series builds on cyclic ideas.

  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 split a cyclic row into a forward segment and a wrap segment - a pattern used far beyond alphabet demos.

🔮 Live Preview

Choose a row count between 1 and 26 and draw the alphabet rotation pattern in the browser.

Try 5 (ABCDE through EDCBA) or 3 (ABC, BCA, CAB). Up to 26 rows use A–Z.

Live result
Press "Draw pattern".

Examples Gallery

Three complete JavaScript programs - fixed five rows with two inner loops, prompt input, and a slice rotation shortcut. Click View Output to reveal sample console results, or Try it Yourself to run in the browser editor.

📚 Getting Started

Print five rotation rows with forward and wrap inner loops.

Example 1 — Fixed rows = 5

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

JavaScript
let rows = 5;
rows = Math.max(1, Math.min(rows, 26));

const base = "A".charCodeAt(0);
const top = base + rows - 1;

for (let i = base; i <= top; i++) {          // A..E
  let line = "";
  for (let j = i; j <= top; j++) {         // i..E (increasing)
    line += String.fromCharCode(j);
  }
  for (let k = i - 1; k >= base; k--) {    // (i-1)..A (decreasing)
    line += String.fromCharCode(k);
  }
  console.log(line);
}
Try it Yourself

How It Works

The outer loop sets each row’s start letter i from A through E. The first inner loop appends forward to the top; the second wraps from the previous letter down to A. When i is the top letter, the wrap loop alone produces the reversed row EDCBA.

📈 Practical Variant

Let the user choose the height at runtime.

Example 2 — User Input Version

Read rows and clamp to 1–26. Validate parseInt(prompt()) with Number.isFinite in real apps.

JavaScript
let rows = parseInt(prompt("Enter number of rows (1-26):"), 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 i = base; i <= top; i++) {
    let line = "";
    for (let j = i; j <= top; j++) {
      line += String.fromCharCode(j);
    }
    for (let k = i - 1; k >= base; k--) {
      line += String.fromCharCode(k);
    }
    console.log(line);
  }
}
Try it Yourself

How It Works

Same two-loop core as Example 1; only the outer bound and clamp change. Three rows use letters A–C with width 3 on every line.

⚡ Slice Shortcut

Rotate a string slice instead of two inner loops.

Example 3 — slice + reverse Variant

Build each row as forward suffix plus reversed prefix - compact and matches the two-loop output.

JavaScript
let rows = 5;
rows = Math.max(1, Math.min(rows, 26));
const letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".slice(0, rows);

for (let i = 0; i < rows; i++) {
  console.log(letters.slice(i) + [...letters.slice(0, i)].reverse().join(""));
}
Try it Yourself

How It Works

letters.slice(i) is the forward part starting at the row letter. [...letters.slice(0, i)].reverse().join("") is the wrap part - same letters as the two-loop wrap, without nested code points.

🧠 How the Algorithm Prints Rows

1

Set up bounds

Clamp rows, then set base = "A".charCodeAt(0) and top = base + rows - 1 for the alphabet window.

base / top
2

Outer loop (start letter)

for (let i = base; i <= top; i++) walks each row’s first letter from A through the top.

A..top
3

Forward + wrap loops

First inner loop appends i through top; second appends i-1 down to A with line += String.fromCharCode(...).

Two loops
4

New line

console.log(line) ends the row after both inner loops finish; the outer loop advances i to the next start letter.

Break
=

Pattern complete

Total characters: n × n = n²O(n²) time, O(1) extra memory (loop version).

🔎 Worked Walkthrough — rows = 5

Trace each outer-loop value of i and see how the forward and wrap parts combine into each printed row.

i (start)Forward partWrap partPrinted row
'A'ABCDE(none)ABCDE
'B'BCDEABCDEA
'C'CDEBACDEBA
'D'DECBADECBA
'E'EDCBAEDCBA

Total character prints: 5 × 5 = 25 = for n = 5 rows.

Use Cases

Where this tiny pattern (and its forward/wrap split) shows up beyond the homework prompt.

1. Contrast with Program 1

Program 1 grows from A - A, AB, ABC. Rotation keeps width fixed and shifts the start.

Example: side-by-side A/AB/ABC vs ABCDE/BCDEA/CDEBA.

2. Descending range practice

Reinforce for (let k = i - 1; k >= base; k--) with immediate visual feedback.

Example: trace wrap part for row 3 (C) on paper before coding.

3. String rotation

The slice form is the same left-rotation used in cipher and buffer problems.

Example: letters.slice(2) + [...letters.slice(0, 2)].reverse().join("") for ABCDE gives CDEBA.

4. Number rotations

Swap letters for digits 1..n with the same forward + wrap logic.

Example: rows=3 gives 123, 231, 312.

5. Complexity intuition

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

Example: 5 rows → 25 characters printed.

6. Interview warm-up

Classic nested-loop question that tests range bounds and wrap logic.

Example: explain why row 5 is EDCBA without running code.

Pro Tip: say “forward to top, wrap down to A” before coding - that story prevents skipping the second inner loop or mixing up range bounds.

Advantages

Why this pattern earns a spot after the basic alphabet triangle from Program 1.

  1. 1. Teaches Wrap-Around

    Two inner loops make cyclic fill explicit before you reach string slicing.

  2. 2. Fixed-Width Rows

    Every line has the same length - easier to verify output than shrinking triangles.

  3. 3. Two Implementations

    Loop version for learning; slice version for compact production code.

  4. 4. O(1) Extra Memory

    Streaming output needs no storage beyond loop counters and code.

Pro Tip: when the start letter equals the top letter, the forward loop prints one character and the wrap loop prints the rest in reverse - that is how EDCBA appears.

Usage Tips

Small habits that keep alphabet rotation pattern code clean.

  1. 1. Name base and top

    Use base and top for letter bounds - keep i, j, k for loop variables.

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

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

  3. 3. Clamp rows early

    rows = max(1, min(rows, 26)) keeps demos inside A–Z.

  4. 4. Trace wrap bounds

    For row start i, wrap runs from i - 1 down to base (stop before base - 1).

  5. 5. Dry-Run rows = 3

    Trace ABC, BCA, CAB on paper before coding larger demos.

Pro Tip: if rows look like Program 1 (A, AB, ABC), you likely restarted from A each row instead of shifting the start letter.

Common Pitfalls

Mistakes that commonly break alphabet rotation patterns.

  1. 1. Skipping the wrap loop

    Only the forward loop prints BCDE, CDE, DE - rows are too short after row 1.

    → Always run the second loop: for (let k = i - 1; k >= base; k--).

  2. 2. Wrong wrap range direction

    An ascending wrap loop walks upward and duplicates forward letters.

    → Wrap must descend: for (let k = i - 1; k >= base; k--).

  3. 3. console.log inside inner loops

    Each letter lands on its own line - you get a column, not rotation rows.

    → Use line += String.fromCharCode(...) in both loops; console.log(line) only after both finish.

  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. Confusing with Program 1

    Program 1 restarts at A and grows width - no cyclic wrap on any row.

    → Here every row has width rows and the start letter shifts forward.

Edge Cases

Check these inputs before calling the solution done.

rows = 1

Single letter

Output is just A on one line - forward and wrap loops both empty except one forward char.

rows = 0

Empty pattern

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

rows = 26

Full alphabet

26 rows of width 26 - last row is a single Z reversed through A (full reverse).

rows > 26

Past Z

Clamp to 26 or define a wrap/error policy before printing.

Bad input

Non-numeric input

Use Number.isFinite before clamping rows.

Case

Lowercase variant

Same loops work with base = "a".charCodeAt(0) and lowercase output.

🎯 Practice Problems

Try these variations to lock in the pattern.

1. Compare with Program 1

  • Program 1: A, AB, ABC (growing, no wrap)
  • This pattern: fixed width, rotated start
  • See Program 1

2. Implement slice form

  • Rewrite Example 1 using letters.slice(i) + [...letters.slice(0, i)].reverse().join("")
  • Verify identical output for rows=5

3. Number rotation

  • Print 123, 231, 312 for rows=3
  • Same forward + wrap logic with ints

4. Continue to Program 27

  • Next pattern in the series
  • Builds on cyclic alphabet ideas
  • See Program 27

Notes

  • Square count. Total characters for n rows is - each row prints n letters.
  • Forward loop: j = i..top. Wrap loop: k = (i-1)..base.
  • letters.slice(i) + [...letters.slice(0, i)].reverse().join("") is equivalent to the two-loop version - use whichever fits your lesson.
  • Clamp to 26 rows for A–Z demos; row 26 starts at Z and wraps through the full alphabet reversed.

Quick Takeaway: outer loop shifts the start letter, forward loop runs to the top, wrap loop fills back to A, then break the line - that is the whole rotation pattern.

⏱️ Time and Space Complexity

ProgramTimeExtra space
Two inner loops (Examples 1–2)O(rows²)O(1)
Slice variant (Example 3)O(rows²)O(rows) for the letters string
Wrap Up

🎉 Conclusion

The alphabet rotation pattern teaches cyclic wrap-around with two inner loops per row - forward to the top letter, then down to A. Master the charCodeAt/fromCharCode version, then try the slice shortcut for the same output in fewer lines.

Practice the three examples above, then continue to Program 27 in the alphabet pattern series.

Set base and top, run forward then wrap loops, clamp rows to 26, and compare with Program 1 to see the difference from growing rows.

💡 Best Practices

✅ Do

  • Set base = "A".charCodeAt(0) and top = base + rows - 1
  • Run forward loop then wrap loop on every row
  • Use line += String.fromCharCode(...) in loops; console.log(line) after both
  • Clamp rows to 1–26 for A–Z demos
  • State O(n²) time and n² character count when asked

❌ Don’t

  • Skip the wrap loop - rows after the first will be too short
  • Use ascending loop for the wrap part
  • Call console.log(line) inside the letter loops
  • Confuse this with Program 1’s growing A/AB/ABC rows
  • Let rows exceed 26 without a defined policy

Key Takeaways

Knowledge Unlocked

Five things to remember about this alphabet pattern

Print the rotation rows the beginner-friendly way.

5
Core concepts
F→ 02

Forward loop

i through top

Code
←A 03

Wrap loop

i-1 down to A

Code
[] 04

Slice shortcut

slice(i) + reverse(prefix)

Alt
O 05

Complexity

O(n²) time

Analysis

❓ Frequently Asked Questions

Each row starts one letter later than the row above but still prints exactly rows characters. Row 1 is ABCDE; row 2 is BCDEA; row 5 is EDCBA - a cyclic shift with wrap-around back to A.
Program 1 grows each row from A (A, AB, ABC, ...) with no wrap. Here every row has the same width (rows letters) and the start letter shifts forward each row, wrapping down to A after reaching the top letter.
The first loop appends forward from the row start letter up to the top letter (E for rows=5). The second loop wraps backward from the previous letter down to A to fill the remaining slots.
It takes the suffix from the row start letter and appends the reversed prefix. For ABCDE with i=2 that gives CDEBA - the same result as the two-loop charCodeAt/fromCharCode version.
Each row uses letters A through the (rows)th letter. With rows > 26 you would need characters beyond Z unless you define a wrap policy.
line += String.fromCharCode(j) stays on the same row with no newline between letters. console.log(line) ends the row after both inner loops finish.
O(n^2) where n is rows. There are n rows and each row prints n characters.
Use parseInt(prompt(), 10) and check Number.isFinite, then clamp rows between 1 and 26.

Did you Know? 🔊

Each row starts one letter later but still prints rows characters: forward from the start letter to the top, then wrap from the previous letter down to A. Row 1 is ABCDE; row 5 becomes EDCBA when the start reaches the top letter.

Continue to Program 27

Next up: right-aligned alphabet pyramid (A, A B, A B C, …).

Program 27 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