Rotating Number Pattern in JavaScript

Beginner
⏱️ 9 min read
📚 Updated: Sep 2026
🎯 3 Code Examples
🚀 Live Preview
Dual Inner Loops

What You’ll Learn

The rotating number pattern prints 12345, then 23451, then 34521, … — each row starts at i and wraps back to 1 — a natural follow-up after Program 38’s decreasing-width triangle. This tutorial covers forward and wrap-around inner loops, row rotation, nested loops, a live preview, worked JavaScript examples, edge cases, and complexity.

Shape Rule

Rotating row

Row i appends i..max_num, then wraps with i-1..1 — exactly max_num digits per row.

Outer Loop

i = 1..max_num

for (let i = 1; i <= max_num; i++) — one rotating row per iteration.

Forward Segment

i..max_num

for (let j = i; j <= max_num; j++) — appends the increasing forward part of the row.

Wrap Segment

i-1..1

for (let k = i - 1; k >= 1; k--) — completes the row with wrap-around digits.

Live Preview

3–9 rows

Pick a row count and draw the rotating number pattern in the browser.

O(n²)

Complexity

Each row appends max_num digits — total digits = .

Introduction

A rotating number pattern prints a circular-shift sequence on each row: 12345, then 23451, then 34521, and so on. With max_num = 5, each row starts at the row number and wraps back to 1.

In JavaScript you use two inner loops per row: append with line += j from i up to max_num, then append with line += k from k = i - 1 down to 1, then console.log(line).

Why it matters?

It combines forward and wrap-around inner loops to build rotation — a step after Program 38’s continuous decreasing triangle.

Key Highlights

i..max_num

Forward segment.

i-1..1

Wrap segment.

n digits

Per row.

Series Foundation

Follow Program 38; continue to Program 40 next.

In short: outer i = 1..max_num, forward j = i..max_num, wrap k = i-1..1, then console.log(line).

📝 Problem & Approach

Given max_num = 5, print a rotating number pattern: for each row i, print ascending i..max_num then wrap with i-1..1.

JavaScript
// max_num = 5
// 12345
// 23451
// 34521
// 45321
// 54321

Inputs & Outputs

ItemTypeDescription
max_numnumberPattern width — highest digit and number of rotating lines.
inumberOuter loop — current row (1 to max_num).
jnumberForward loop — ascending from i to max_num.
knumberWrap loop — descending from i - 1 to 1.

Minimal workflow

Pseudocode
for i from 1 to max_num:
    for j from i to max_num: print j
    for k from i-1 down to 1: print k
    print newline

Approach comparison

ApproachIdeaBest for
Fixed max_num12345, 23451, …Learning and interviews
User inputparseInt(prompt(), 10)Configurable pattern size
Compact tracemax_num = 3 on paper firstDebugging loop bounds

⚡ Quick Reference

GoalPattern
Outer loopfor (let i = 1; i <= max_num; i++)
Forward segmentfor (let j = i; j <= max_num; j++) line += j
Wrap segmentfor (let k = i - 1; k >= 1; k--) line += k
End the rowconsole.log(line)
User inputmax_num = parseInt(prompt("Enter the maximum number:"), 10)

📋 line += vs join vs array build

Same rotating number pattern — different ways to emit each row.

line += j
same row

Classic nested-loop approach — appends each digit to a string

parts.join("")
whole row

Build the row array first, then join and log once per line

k from i-1 to 1
wrap

Descending wrap segment from i-1 down to 1

Learning tip
loops first

Master the two inner loops before the join shortcut

Context

When This Pattern Shows Up

Reach for this pattern when teaching forward and wrap-around inner loops, circular rotation, and sequence design.

  1. After Program 38

    Natural follow-up — replaces decreasing-width rows with rotating sequences built from forward and wrap loops.

  2. Rotation drills

    Practice forward then wrap loops to build circular-shift sequences on each row.

  3. Console I/O practice

    Combine loops with prompt() and validation for flexible row counts.

  4. Gateway to variants

    Compare Program 38 (decreasing) and Program 40 (alternating 1/0) next.

  5. Not a UI layout tool

    This is a console teaching pattern — not how you build modern app screens.

Key benefit: one small program that locks in dual inner loops, wrap-around logic, and O(n²) thinking.

🔮 Live Preview

Choose a row count between 3 and 9 and draw the rotating number pattern in the browser.

Try 3, 5, or 7. Rows between 3 and 9 in this preview.

Live result
Press "Draw pattern".

Examples Gallery

Three complete JavaScript programs — fixed width, prompt() input, and a smaller trace demo. Click View Output to reveal sample console results, or Try it Yourself to run the code live.

📚 Getting Started

Print five rows of the rotating number pattern with forward and wrap-around inner loops.

Example 1 — Fixed max_num = 5

Hard-coded width — ideal for first demos and screenshots.

JavaScript
const max_num = 5;

for (let i = 1; i <= max_num; i++) {
  let line = "";
  for (let j = i; j <= max_num; j++) {
    line += j;
  }
  for (let k = i - 1; k >= 1; k--) {
    line += k;
  }
  console.log(line);
}
Try it Yourself

How It Works

When i = 3, the forward loop appends 3 4 5, the wrap loop appends 2 1 — output 34521. When i = 1, only the forward loop runs — output 12345.

📈 User Input

Read the maximum number with prompt() instead of hard-coding 5.

Example 2 — User Input Version

Read max_num with prompt() and parseInt() (check with Number.isFinite in real apps).

JavaScript
const maxInput = prompt("Enter the maximum number:");
const max_num = parseInt(maxInput, 10);

if (!Number.isFinite(max_num) || max_num < 1) {
  console.log("Please enter a positive integer.");
} else {
  for (let i = 1; i <= max_num; i++) {
    let line = "";
    for (let j = i; j <= max_num; j++) {
      line += j;
    }
    for (let k = i - 1; k >= 1; k--) {
      line += k;
    }
    console.log(line);
  }
}
Try it Yourself

How It Works

Same rotating core as Example 1; only max_num comes from user input instead of being hard-coded as 5. Non-numeric input yields NaN with bare parseInt() — use Number.isFinite for safer labs.

⚡ Smaller Demo

Run with max_num = 3 to trace every row on paper before scaling up.

Example 3 — Compact max_num = 3

Same forward and wrap loops with a smaller width for quick tracing.

JavaScript
const max_num = 3;

for (let i = 1; i <= max_num; i++) {
  let line = "";
  for (let j = i; j <= max_num; j++) {
    line += j;
  }
  for (let k = i - 1; k >= 1; k--) {
    line += k;
  }
  console.log(line);
}
Try it Yourself

How It Works

Only max_num changes from 5 to 3 — the two inner loops stay identical. Trace i = 1, 2, 3 on paper to see how each row rotates the sequence.

🧠 How the Algorithm Prints Rows

1

Set up

No imports needed for fixed width; use prompt() when reading. Set max_num = 5.

Setup
2

Outer loop walks rows

for (let i = 1; i <= max_num; i++) — ascending outer loop; one rotating row per iteration.

Row
3

Forward segment

for (let j = i; j <= max_num; j++) — appends i, i+1, ..., max_num via line += j.

Forward
4

Wrap segment

for (let k = i - 1; k >= 1; k--) — appends i-1, i-2, ..., 1 via line += k.

Wrap
5

New line

console.log(line) ends the row after both inner loops finish.

Break
=

Rotating pattern complete

Each row prints exactly max_num digits — total digits = ; O(n²) time.

🔎 Worked Walkthrough — max_num = 5

Trace each outer-loop value of i, forward and wrap segments, and full row output.

iForward (i..max_num)Wrap (i-1..1)Row output
11, 2, 3, 4, 512345
22, 3, 4, 5123451
33, 4, 52, 134521
44, 53, 2, 145321
554, 3, 2, 154321

Each row prints exactly max_num digits — total digits = n × n = n².

Use Cases

Where this tiny pattern (and its loop structure) shows up beyond the homework prompt.

1. Teaching Dual Inner Loops

Forward then wrap loops show how two segments build one fixed-width row.

Example: swap forward and wrap loops and watch the rotation break.

2. Pattern Series Base

Foundation for rotation-based patterns and circular-shift sequences.

Example: compare with Program 38 and Program 40.

3. Console Formatting Drills

Practice concatenated digit output with line += before each console.log(line).

Example: add a space after each digit for a spaced rotation variant.

4. Alphabet rotation

Swap digits for letters once the two-loop structure works.

Example: use String.fromCharCode(64 + j) for an A..E rotation pattern.

5. Complexity Intuition

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

Example: count printed digits for n = 5 → 25.

6. Input Validation Labs

Pair the pattern with Number.isFinite and positive-width checks.

Example: reject max_num <= 0 and re-prompt.

Pro Tip: think of each row as two concatenated sequences — an ascending prefix and a descending suffix. That split makes many rotation patterns easier.

Advantages

Why this pattern earns a permanent spot in beginner JavaScript courses.

  1. 1. Instant Visual Feedback

    Wrong bounds show up immediately as broken or short rows.

  2. 2. Minimal Concepts

    Only nested loops and console.log — no arrays or math libraries.

  3. 3. Easy to Extend

    Switch to cyclic ascending wrap, letters, or spaced output with small edits.

  4. 4. O(1) Extra Memory

    Streaming output needs no storage beyond loop counters.

Pro Tip: learn the two-loop version first; treat parts.join("") as a polish shortcut afterward.

Usage Tips

Small habits that keep rotating number-pattern code clean.

  1. 1. Name Variables Clearly

    Use max_num for width and keep i/j/k for row/forward/wrap loops.

  2. 2. Validate with Number.isFinite

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

  3. 3. Keep console.log Outside Inner Loops

    Only call console.log(line) after both inner loops finish the row.

  4. 4. Trace max_num = 3 First

    Smaller width makes forward and wrap segments easy to verify on paper.

  5. 5. Check Row Length

    Every row should print exactly max_num digits — a quick sanity check.

Pro Tip: if rows have different lengths, you almost certainly mixed up the wrap loop range.

Common Pitfalls

Mistakes that commonly break rotating number patterns.

  1. 1. console.log Inside the Inner Loop

    Each digit lands on its own line — you get a column, not a rotating row.

    → Use line += j for digits; console.log(line) only after both inner loops.

  2. 2. Wrong Wrap Range

    for (let k = 1; k < i; k++) appends ascending wrap; k >= i in the wrap loop includes i twice.

    → For this shape, keep for (let k = i - 1; k >= 1; k--).

  3. 3. Forgetting the Row Break

    Omitting console.log(line) glues every digit onto one endless line.

    → Always end the row after both inner loops.

  4. 4. Unchecked parseInt(prompt())

    Letters or empty input yield NaN with bare parseInt().

    → Check Number.isFinite(max_num) and re-prompt on failure.

  5. 5. Hardcoding 5 Everywhere

    Changing only the variable but not loop bounds breaks generalization.

    → Use max_num in both for (let i = 1; i <= max_num; i++) and for (let j = i; j <= max_num; j++).

Edge Cases

Check these inputs before calling the solution done.

max_num = 1

Single digit

Output is just 1 on one line — wrap loop does not run.

max_num = 0

Empty pattern

Outer loop never runs — print nothing or show a message.

Negative

max_num < 0

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

Large n

Many rows

Output grows as n² characters — fine for labs, noisy for huge n.

Bad input

Non-numeric input

Bare parseInt(prompt()) yields NaN — use Number.isFinite first.

Cyclic variant

Ascending wrap

Use for (let k = 1; k < i; k++) instead of descending wrap for a pure cycle.

🎯 Practice Problems

Try these variations to lock in the pattern.

1. Cyclic ascending wrap

  • Replace for (let k = i - 1; k >= 1; k--) with for (let k = 1; k < i; k++)
  • Produces 23451, 34512, … style rows

2. Spaced output

  • Print a space after each digit
  • Easier to read for wider patterns

3. Safe input loop

  • Use Number.isFinite until max_num >= 1
  • Then draw the rotating pattern

4. Alphabet rotation

  • Swap digits for A..E letters
  • Same two-loop structure

Notes

  • Square count. Total digits for n rows is — hence O(n²) time.
  • line += j builds the row; console.log(line) advances — call log only after both inner loops.
  • Validate max_num > 0 for interactive programs; max_num = 1 should print a single 1.
  • Row 1 has no wrap segment — only the forward loop runs when i = 1.

Quick Takeaway: forward loop prints i..max_num, wrap loop prints i-1..1, then break the line — that is the whole pattern.

⏱️ Time and Space Complexity

ProgramTimeExtra space
Nested loops (Examples 1–2)O(max_num²)O(1)
Compact demo (Example 3)O(max_num²)O(1)
Wrap Up

🎉 Conclusion

The rotating number pattern is a compact dual-loop exercise with lasting payoff: forward and wrap segments, fixed row width, and O(n²) intuition. Master the classic two-inner-loop version, then optionally try cyclic or spaced variants.

Practice the three examples above, then continue to Program 40 for the alternating 1/0 triangle pattern.

Row i appends i..max_num then i-1..1 — build with line += and break with console.log(line).

💡 Best Practices

✅ Do

  • Explain forward and wrap segments before coding
  • Use line += j for digits and console.log(line) after each row
  • Validate max_num ≥ 1 for interactive programs
  • Check Number.isFinite(max_num) after parseInt(prompt())
  • State O(n²) time when asked about complexity

❌ Don’t

  • Call console.log(line) inside the inner digit loops
  • Use k >= i in the wrap loop when you meant k = i - 1; k >= 1
  • Skip the newline after each row
  • Ignore bad console input in user-facing demos
  • Skip the max_num = 1 edge case

Key Takeaways

Knowledge Unlocked

Five things to remember about this rotating pattern

Print the pattern the beginner-friendly way.

5
Core concepts
02

Forward loop

for (let j = i; j <= max_num; j++)

Code
03

Wrap loop

for (let k = i - 1; k >= 1; k--)

Code
n 04

Fixed width

max_num digits per row

Shape
O 05

Complexity

O(n²) time

Analysis

❓ Frequently Asked Questions

For max_num = 5: 12345, 23451, 34521, 45321, 54321 — each row starts at the row number and wraps back to 1.
The first loop appends i..max_num (forward segment). The second loop appends i-1 down to 1 (wrap segment). Together they always produce max_num digits.
After appending 2 3 4 5, the wrap loop runs for k from i - 1 down to 1 — for i=2 that appends 1.
Exactly max_num digits every time — (max_num - i + 1) forward plus (i - 1) wrap = max_num.
Program 38 appends a shrinking-width continuous sequence. Program 39 rotates: i..max_num then i-1..1 on every row.
Set max_num to a new value or read it with prompt() — see Example 2.
O(n²) for n rows because each row appends n digits.
Yes. Instead of descending wrap k from i-1 to 1, append ascending 1..i-1 to complete a cycle.
Use parseInt with Number.isFinite or validate the raw string before converting so bad input does not produce NaN.

Did you Know? 🔊

Each row starts at i, appends i..max_num, then wraps with i-1..1. Row i always appends exactly max_num digits — total digits = .

Continue to Program 40

Move on to the alternating 1/0 triangle pattern in the JavaScript number-pattern series.

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