Rotation Rule
Shift start, fixed width
Every row prints exactly rows letters; the first letter moves one step forward each row.

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.
Shift start, fixed width
Every row prints exactly rows letters; the first letter moves one step forward each row.
Start → top
for (let j = i; j <= top; j++) appends from the row start up to the top letter.
Previous → A
for (let k = i - 1; k >= base; k--) fills remaining slots wrapping back to A.
Letter codes
base = "A".charCodeAt(0) and top = base + rows - 1 bound the alphabet window.
1–26 rows
Pick a row count and draw the rotation pattern in the browser instantly.
Complexity
n rows × n letters per row = n² total characters; extra memory stays O(1).
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.
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.
Every row prints exactly rows letters - unlike Program 1’s growing triangle.
Outer loop walks start letters from A through the top letter.
Second inner loop prints from the previous letter down to A.
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.
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.
// First 5 rows
// ABCDE
// BCDEA
// CDEBA
// DECBA
// EDCBA | Item | Type | Description |
|---|---|---|
rows | int | Number of rows and width of each row. Clamp to 1–26 for A–Z demos. |
| Printed output | text | Fixed-width uppercase rows with cyclic wrap - no spaces between letters. |
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 | Idea | Best for |
|---|---|---|
| Two inner loops | Forward j = i..top + wrap k = (i-1)..base | Learning charCodeAt/fromCharCode and loop bounds |
| Slice rotation | letters.slice(i) + [...letters.slice(0, i)].reverse().join("") | Compact production code |
| Program 1 style | See Program 1 (A, AB, ABC, …) | Growing rows, no wrap-around |
| Goal | Pattern |
|---|---|
| Bound the alphabet | base = "A".charCodeAt(0); top = base + rows - 1 |
| Outer loop (start letter) | for (let i = base; i <= top; i++) |
| Forward part | for (let j = i; j <= top; j++) line += String.fromCharCode(j) |
| Wrap part | for (let k = i - 1; k >= base; k--) line += String.fromCharCode(k) |
| End the row | console.log(line) |
| Slice shortcut | console.log(letters.slice(i) + [...letters.slice(0, i)].reverse().join("")) |
Three ways to build the same rotation rows - pick based on what you are learning.
j = i; j <= top; j++
i..EAppends from the row start letter up to the top - ABCDE starts with all five forward.
k = i-1; k >= base; k--
..AFills remaining slots wrapping down - BCDEA adds A after BCDE.
letters.slice(i)
+ reverse(prefix)One expression per row - same output, less loop bookkeeping.
reset A
no wrapProgram 1 grows rows from A - A, AB, ABC - with no cyclic fill.
Reach for rotation loops when each row is fixed width but the starting token shifts cyclically.
Program 1 grows from A with no wrap - this keeps width fixed and rotates the start.
Practice forward and descending ranges on the same row before using slices.
The slice form letters.slice(i) + [...letters.slice(0, i)].reverse().join("") matches the forward + reversed-prefix loops.
Next pattern in the alphabet series builds on cyclic ideas.
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.
Choose a row count between 1 and 26 and draw the alphabet rotation pattern in the browser.
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.
Print five rotation rows with forward and wrap inner loops.
rows = 5Hard-coded height - ideal for first demos and screenshots.
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);
} 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.
Let the user choose the height at runtime.
Read rows and clamp to 1–26. Validate parseInt(prompt()) with Number.isFinite in real apps.
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);
}
} 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.
Rotate a string slice instead of two inner loops.
slice + reverse VariantBuild each row as forward suffix plus reversed prefix - compact and matches the two-loop output.
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(""));
} 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.
Clamp rows, then set base = "A".charCodeAt(0) and top = base + rows - 1 for the alphabet window.
for (let i = base; i <= top; i++) walks each row’s first letter from A through the top.
First inner loop appends i through top; second appends i-1 down to A with line += String.fromCharCode(...).
console.log(line) ends the row after both inner loops finish; the outer loop advances i to the next start letter.
Total characters: n × n = n² — O(n²) time, O(1) extra memory (loop version).
rows = 5Trace each outer-loop value of i and see how the forward and wrap parts combine into each printed row.
i (start) | Forward part | Wrap part | Printed row |
|---|---|---|---|
'A' | ABCDE | (none) | ABCDE |
'B' | BCDE | A | BCDEA |
'C' | CDE | BA | CDEBA |
'D' | DE | CBA | DECBA |
'E' | E | DCBA | EDCBA |
Total character prints: 5 × 5 = 25 = n² for n = 5 rows.
Where this tiny pattern (and its forward/wrap split) shows up beyond the homework prompt.
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.
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.
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.
Swap letters for digits 1..n with the same forward + wrap logic.
Example: rows=3 gives 123, 231, 312.
Square totals make O(n²) concrete for beginners.
Example: 5 rows → 25 characters printed.
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.
Why this pattern earns a spot after the basic alphabet triangle from Program 1.
Two inner loops make cyclic fill explicit before you reach string slicing.
Every line has the same length - easier to verify output than shrinking triangles.
Loop version for learning; slice version for compact production code.
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.
Small habits that keep alphabet rotation pattern code clean.
Use base and top for letter bounds - keep i, j, k for loop variables.
parseInt(prompt(), 10) in Number.isFiniteAvoid crashes when the user types letters instead of a number.
rows = max(1, min(rows, 26)) keeps demos inside A–Z.
For row start i, wrap runs from i - 1 down to base (stop before base - 1).
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.
Mistakes that commonly break alphabet rotation patterns.
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--).
An ascending wrap loop walks upward and duplicates forward letters.
→ Wrap must descend: for (let k = i - 1; k >= base; k--).
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.
Non-numeric input yields NaN with bare parseInt(prompt()).
→ Validate parseInt(prompt()) with Number.isFinite and validate range.
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.
Check these inputs before calling the solution done.
Output is just A on one line - forward and wrap loops both empty except one forward char.
Treat as invalid; re-prompt instead of silent empty output.
26 rows of width 26 - last row is a single Z reversed through A (full reverse).
Clamp to 26 or define a wrap/error policy before printing.
Use Number.isFinite before clamping rows.
Same loops work with base = "a".charCodeAt(0) and lowercase output.
Try these variations to lock in the pattern.
letters.slice(i) + [...letters.slice(0, i)].reverse().join("")n rows is n² - each row prints n letters.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.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.
| Program | Time | Extra space |
|---|---|---|
| Two inner loops (Examples 1–2) | O(rows²) | O(1) |
| Slice variant (Example 3) | O(rows²) | O(rows) for the letters string |
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.
base = "A".charCodeAt(0) and top = base + rows - 1line += String.fromCharCode(...) in loops; console.log(line) after bothconsole.log(line) inside the letter loopsPrint the rotation rows the beginner-friendly way.
Fixed width, shifted start
Definitioni through top
Codei-1 down to A
Codeslice(i) + reverse(prefix)
AltO(n²) time
AnalysisEach 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.
Next up: right-aligned alphabet pyramid (A, A B, A B C, …).
12 people found this page helpful