JavaScript Sequential Number Triangle Pattern (Narrowing)

Beginner
5 min read
Updated: Sep 2026
3 programs
Live preview

What Is This Pattern?

A sequential decreasing-width triangle prints one continuous sequence — row 1 has n values, row 2 has n-1, and so on down to a single number.

Remember
Rule: k = 1; for i = 1..rows
      print (rows - i + 1) values of k with padStart(3)

  1  2  3  4  5
  6  7  8  9
 10 11 12
 13 14
 15                 ← rows = 5

After Program 37’s palindrome rows, this pattern focuses on a shared counter and shrinking inner bounds.

How to Solve It

Walk i from 1 to rows; on each row append rows - i + 1 values from counter k.

MethodIdeaBest for
Counter + shrinkInner j = rows..i; padStart(3) and k++Learning, interviews
prompt rowsSame loops; read rows at runtimeInteractive practice
Custom start kSame shape; initialize k to any start valueSequence variants

Pseudocode

Pseudocode
k = 1
for i from 1 to rows:
    line = ""
    for j from rows down to i:
        line += pad(k, width 3)
        k += 1
    print line

Cheat sheet

GoalPattern
Set rows / counterconst rows = 5; let k = 1;
Outer loopfor (let i = 1; i <= rows; i++)
Inner loopfor (let j = rows; j >= i; j--)
Number cellline += String(k).padStart(3, " "); k += 1;
End rowconsole.log(line);
Values per rowrows - i + 1
Total valuesn(n+1)/2 for n rows

Printing Numbers vs Starting a New Line

APIEffectUse for
line += String(k).padStart(3, " ")Stays on the same rowEach cell
console.log(line)Ends the lineAfter the inner loop

Build the row with +=, then break once with console.log. Putting console.log inside the inner loop prints one cell per line.

Live Preview

Change the row count and the sequential triangle updates instantly.

Whole numbers from 1 to 9. Tap a chip or type a value — the preview redraws as you go.

Live result rows = 5 · values = 15
  1  2  3  4  5
  6  7  8  9
 10 11 12
 13 14
 15

Worked Walkthrough — rows = 3

Trace each outer i, how many values the inner loop prints, the k range, and the printed row.

iInner runsk rangePrinted row
131..31 2 3
224..54 5
3166

Inner runs = rows - i + 1. Counter k never resets between rows. Total values = 6 = 3×4/2.

JavaScript Programs

Three complete programs: fixed rows = 5, prompt rows, and custom start k = 10. Use View Output for sample results, or Try It Yourself to edit and run in the playground.

Example 1 — Fixed rows = 5

Hard-coded height — shrinking inner loop, continuous k, and padStart(3).

JavaScript
const rows = 5;
let k = 1;

for (let i = 1; i <= rows; i++) {
  let line = "";
  for (let j = rows; j >= i; j--) {
    line += String(k).padStart(3, " ");
    k += 1;
  }
  console.log(line);
}
Try It Yourself

How It Works

1. Counter. k starts at 1 and increments after every cell — the sequence never resets between rows.

2. Shrinking inner loop. j runs from rows down to i, so row 1 prints 5 values, row 2 prints 4, and so on.

3. Alignment. padStart(3, " ") keeps two-digit numbers (10–15) lined up with single digits.

Example 2 — prompt Rows

Read rows at runtime with prompt and parseInt.

JavaScript
const rows = parseInt(prompt("Enter rows:"), 10);

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

How It Works

1. Prompt and validate. Parse the answer; reject non-positive or non-numeric input.

2. Same shape. The inner bound still uses rows and i — only the outer limit changes.

3. Counter restarts at 1. Each run begins a fresh sequence from k = 1.

Example 3 — Custom Start k = 10

Same shrinking triangle, but the continuous sequence begins at 10 instead of 1.

JavaScript
const rows = 5;
let k = 10;

for (let i = 1; i <= rows; i++) {
  let line = "";
  for (let j = rows; j >= i; j--) {
    line += String(k).padStart(3, " ");
    k += 1;
  }
  console.log(line);
}
Try It Yourself

How It Works

1. Only k changes. Loops and padStart match Example 1 — just initialize k = 10.

2. Same total count. Still 15 values for rows = 5; they just run from 10 through 24.

3. Try other starts. Set k = 100 or any integer once you understand the default.

Edge Cases & Pitfalls

Check these before calling the solution done.

reset k

Broken sequence

If you set k = 1 inside the outer loop, every row restarts at 1 instead of continuing.

inner bound

Wrong width

Use j >= i, not j >= 1. Stopping at 1 prints a full rectangle of n² values.

log inside

Vertical cells

If console.log is inside the inner loop, each number lands on its own line.

no padStart

Crooked columns

Without padStart(3), single-digit and two-digit cells misalign once k ≥ 10.

rows = 1

Single cell

Output is one padded value — the starting k.

NaN input

Validate parseInt

Letters or empty prompt yield NaN — check Number.isFinite(rows) && rows >= 1.

Time and Space Complexity

ProgramTimeExtra space
Examples 1–3O(n²)O(n) for the current line string

Values per pattern = n + (n-1) + … + 1 = n(n+1)/2 → O(n²).

Key Takeaways

  • Rule: print rows - i + 1 consecutive values of k on each row.
  • Shared counter: initialize k once; never reset it inside the outer loop.
  • Write vs log: line += padStart(k) builds; console.log(line) breaks.
  • Complexity: total values = n(n+1)/2 → O(n²).

One line: shrink the inner count each row while a shared k keeps counting upward.

Frequently Asked Questions

Row lengths are 5, 4, 3, 2, and 1. Their sum is 5+4+3+2+1 = 15, which equals n(n+1)/2.
padStart(3, " ") right-aligns each integer in a 3-character field so columns stay neat when numbers reach two digits.
Each row prints a different count of values, but the sequence must continue globally (1, 2, 3, …). k stores the next value and increments after every append.
Yes. Initialize k with your starting value instead of 1 — see Example 3 with k = 10.
Program 37 builds a palindrome on each row (4321234). Program 38 appends one continuous ascending sequence with shrinking row widths.
Replace 5 with rows in the outer loop bound — see Example 2.
O(n²) where n is the number of rows. Total appended values equal 1+2+…+n = n(n+1)/2.
Use parseInt with Number.isFinite so bad input does not produce NaN.
Only one row prints — a single padded 1.

Did you know?

Row i appends rows - i + 1 consecutive numbers via a shared k counter. Total values for n rows is the triangular number n(n+1)/2 — 15 when rows = 5.

Next: Rotating Numbers

Continue with the next pattern in the JavaScript number-pattern series.

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