Column-Wise Number Triangle in JavaScript

Beginner
⏱️ 10 min read
📚 Updated: Sep 2026
🎯 3 Code Examples
🚀 Live Preview
Nested Loops + 2D Array

What You’ll Learn

Program 55 logs a column-wise number triangle: fill a 2D array column by column with increasing numbers, then log row by row — a natural step after Program 54’s mirror diagonal diamond. This tutorial covers column-wise filling, row-wise logging, a live preview, worked JavaScript examples, edge cases, and complexity.

Shape Rule

Column-wise fill

Fill column 1 with 1..rows, column 2 with the next block, and so on — then log each row left to right.

2D Array

tri[row][col]

const tri = Array.from({ length: rows + 1 }, () => Array(rows + 1).fill(0)); stores values so fill order and log order can differ.

Fill Loop

col outer, row inner

for (let col = 1; col <= rows; col++) { for (let row = col; row <= rows; row++) { tri[row][col] = num; num++; } } — column-wise assignment.

Print Loop

row outer, col inner

for (let row = 1; row <= rows; row++) { let line = ""; for (let col = 1; col <= row; col++) { line += tri[row][col] + (col < row ? " " : ""); } console.log(line); } — standard triangle output.

Live Preview

rows = 3..9

Pick row count and draw the column-wise triangle in the browser.

O(n²)

Complexity

Total values = 1+2+…+n = n(n+1)/2 — classic triangular number complexity.

Introduction

A column-wise number triangle fills numbers down each column first, then prints row by row — creating jumps like 2 6 and 3 7 10 instead of consecutive digits. With rows = 5, you get 1, 2 6, 3 7 10, 4 8 11 13, 5 9 12 14 15.

In JavaScript, create a 2D array, fill with nested loops (col outer, row inner), then log with reversed nesting (row outer, col inner).

Why it matters?

It bridges Program 54’s conditional patterns to 2D array storage — teaching fill order vs log order as separate steps.

Key Highlights

Column fill

Outer col, inner row = col..rows.

Row print

Outer row, inner col = 1..row.

vs Program 54

Program 54 uses diagonal conditions; Program 55 uses a 2D array with column-wise filling.

Series Foundation

Follow Program 54; continue to Program 56 next.

In short: fill tri[row][col] = num; num++ column-wise, then build each row string from tri[row][col] and console.log(line).

📝 Problem & Approach

Given row count rows = 5, fill a triangle column-wise with increasing numbers, then log row-wise.

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

Inputs & Outputs

ItemTypeDescription
rowsnumberTriangle height — row i logs i values.
tri[row][col]2D number array2D array storing filled values — 1-based indexing.
numnumberRunning counter incremented during column-wise fill.
col (fill outer)numberColumn index — runs 1 to rows.
row (fill inner)numberRuns col..rows for each column during fill.
Max valuenumberLargest logged number = rows*(rows+1)/2.

Minimal workflow

Pseudocode
create tri[rows+1][rows+1]
num = 1
for col from 1 to rows:
    for row from col to rows:
        tri[row][col] = num
        num++
for row from 1 to rows:
  line = ""
  for col from 1 to row:
    line += tri[row][col] + space if needed
  console.log(line)

Approach comparison

ApproachIdeaBest for
2D array + column fillFill column-wise, log row-wiseThis distinctive jump pattern
Row-wise fillStandard 1, 2 3, 4 5 6 triangleComparison / simpler output
User-input rowsparseInt(prompt())Flexible triangle size
Compact tracerows = 3 on paper firstQuick dry-runs (6 cells total)
Fixed-width printString(val).padStart(3) in line buildingAlignment when rows exceed 9

⚡ Quick Reference

GoalPattern
Declare arrayconst tri = Array.from({ length: rows + 1 }, () => Array(rows + 1).fill(0));
Fill column-wisefor (let col = 1; col <= rows; col++) for (let row = col; row <= rows; row++) tri[row][col] = num++;
Log row-wisefor (let row = 1; row <= rows; row++) { let line = ""; for (let col = 1; col <= row; col++) line += tri[row][col] + (col < row ? " " : ""); console.log(line); }
Add spacingif (col < row) line += " " between values
End rowconsole.log(line);
Program 54 contrastProgram 54 uses diagonal conditions; Program 55 uses 2D array column fill

📋 Fixed Rows vs User Input vs Compact Trace

Same column-wise triangle — three ways to set row count and trace the fill order.

Fixed rows
rows = 5

Hard-coded height for demos (15 values)

User input
parseInt(prompt())

Read row count from console

Compact trace
rows = 3

6-cell triangle for paper tracing

Fill order
col outer

Column-wise assignment

Print order
row outer

Row-wise display

Context

When This Pattern Shows Up

Reach for this pattern when teaching 2D arrays, fill order vs log order, and triangular number sequences.

  1. Post Program 54 exercise

    Natural follow-up after Program 54’s diamond — introduces 2D array storage and column-wise filling.

  2. 2D array drills

    Fill in one order, print in another — a pattern used in matrices, grids, and game boards.

  3. Triangular numbers

    Total cells = n(n+1)/2 — links loops to the triangular number formula.

  4. Gateway to Program 56

    Compare column-wise fill with the next pattern in the series.

  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 2D arrays, fill/log order separation, and O(n²) thinking.

🔮 Live Preview

Choose row count between 3 and 9 and draw the column-wise number triangle in the browser.

Try 4, 5, or 7. Max up to 9 in this preview.

Live result
Press "Draw pattern".

Examples Gallery

Three complete JavaScript programs — fixed rows, user input, and a compact trace demo. Click View Output to reveal sample console results, or Try it Yourself to run in the browser.

📚 Getting Started

Fill a 5-row triangle column-wise into a 2D array, then log row-wise with spaces.

Example 1 — Fixed rows = 5

Hard-coded row count — fill with col outer and row = col..rows inner, then log with row outer and col = 1..row inner.

JavaScript
const rows = 5;
const tri = Array.from({ length: rows + 1 }, () => Array(rows + 1).fill(0));
let num = 1;

for (let col = 1; col <= rows; col++) {
  for (let row = col; row <= rows; row++) {
    tri[row][col] = num;
    num++;
  }
}

for (let row = 1; row <= rows; row++) {
  let line = "";
  for (let col = 1; col <= row; col++) {
    line += tri[row][col];
    if (col < row) line += " ";
  }
  console.log(line);
}
Try it Yourself

How It Works

Column 1 fills rows 1–5 with 1–5. Column 2 fills rows 2–5 with 6–9. When logged row-wise, row 2 shows 2 6 — values from columns 1 and 2 of that row.

📈 User Input

Read row count with prompt() and Number.isFinite validation.

Example 2 — User Input Rows

Read rows with prompt() and validate the result.

JavaScript
const rowsInput = prompt("Enter the number of rows:");
const rows = parseInt(rowsInput, 10);

if (!Number.isFinite(rows) || rows < 1) {
  console.log("Please enter a positive integer.");
} else {
  const tri = Array.from({ length: rows + 1 }, () => Array(rows + 1).fill(0));
  let num = 1;

  for (let col = 1; col <= rows; col++) {
    for (let row = col; row <= rows; row++) {
      tri[row][col] = num;
      num++;
    }
  }

  for (let row = 1; row <= rows; row++) {
    let line = "";
    for (let col = 1; col <= row; col++) {
      line += tri[row][col];
      if (col < row) line += " ";
    }
    console.log(line);
  }
}
Try it Yourself

How It Works

Same column-fill then row-log core as Example 1; only the source of rows changes from a literal to user input.

⚡ Compact Trace

Smaller row count for quick tracing on paper or in interviews.

Example 3 — Compact rows = 3

Use rows = 3 to trace column fill (6 cells) before scaling to 5 rows.

JavaScript
const rows = 3;
const tri = Array.from({ length: rows + 1 }, () => Array(rows + 1).fill(0));
let num = 1;

for (let col = 1; col <= rows; col++) {
  for (let row = col; row <= rows; row++) {
    tri[row][col] = num;
    num++;
  }
}

for (let row = 1; row <= rows; row++) {
  let line = "";
  for (let col = 1; col <= row; col++) {
    line += tri[row][col];
    if (col < row) line += " ";
  }
  console.log(line);
}
Try it Yourself

How It Works

Only six cells to fill — column 1 gets 1–3, column 2 gets 4–5, column 3 gets 6. Trace each assignment on paper before running rows = 5.

🧠 How the Algorithm Fills and Prints

1

Create the 2D array

const tri = Array.from({ length: rows + 1 }, () => Array(rows + 1).fill(0)); — 1-based indexing for rows and columns.

Setup
2

Fill column-wise

for (let col = 1; col <= rows; col++) for (let row = col; row <= rows; row++) tri[row][col] = num++;.

Fill
3

Print row-wise

for (let row = 1; row <= rows; row++) — build each line from stored values with spaces, then console.log(line).

Print
4

Understand the jumps

Row 2 shows 2 6 because column 1 has 2 and column 2 has 6 at row 2 — not consecutive fill order.

Logic
=

Column-wise triangle complete

Total values = n(n+1)/2O(n²) time, O(n²) array space.

🔎 Worked Walkthrough — rows = 5

Trace column-wise fill assignments and the resulting row output.

ColumnFills rowsValues assigned
11..51, 2, 3, 4, 5
22..56, 7, 8, 9
33..510, 11, 12
44..513, 14
5515
rowColumns loggedRow output
1col 11
2col 1–22 6
3col 1–33 7 10
4col 1–44 8 11 13
5col 1–55 9 12 14 15

The jump from 2 to 6 on row 2 happens because column 2 was filled after column 1 — not because of a formula on the row itself.

Use Cases

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

1. Teaching Nested Loops

Column-wise fill then row-wise log — two distinct loop phases.

Example: trace the fill table and row output table in the walkthrough.

2. Fill-Order Drills

Changing fill order (column vs row) completely changes the output — compare both on paper.

Example: row 5 shows all five columns: 5 9 12 14 15.

3. Output Formatting Drills

Practice line += tri[row][col] vs console.log(line) with multiple values per row.

Example: put console.log(line) inside the inner loop by mistake.

4. Triangular Numbers

Total cells = n(n+1)/2 — the nth triangular number.

Example: Peak row 10 fills 55 cells — largest value is 55.

5. Complexity Intuition

Growing inner bound makes O(n²) concrete — count prints for n rows.

Example: Peak row 5 fills 15 cells — see the walkthrough table.

6. Input Validation Labs

Pair the pattern with Number.isFinite and positive-row validation after parseInt(prompt()).

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

Pro Tip: when an interviewer asks for patterns, explain outer/inner roles first — then write the loops. The story matters as much as the code.

Advantages

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

  1. 1. Instant Visual Feedback

    Swapping fill and print loop nesting without an array produces scrambled output.

  2. 2. Real Math Connection

    Column-wise fill teaches real 2D array usage — not abstract loop drill.

  3. 3. Easy to Extend

    Change rows, use fixed-width format, or switch to full rectangular table.

  4. 4. O(1) Extra Memory

    Streaming output needs no storage beyond loop counters.

Pro Tip: trace rows = 3 on paper — 6 cells, output 1 / 2 4 / 3 5 6.

Usage Tips

Small habits that keep number-pattern code clean.

  1. 1. Fill col outer, row inner

    Column-wise fill: for (let col = 1; col <= rows; col++) for (let row = col; row <= rows; row++).

  2. 2. Validate with Number.isFinite

    Avoid using uninitialized rows when the user types letters instead of a number.

  3. 3. console.log After Row String

    Only call console.log(line) after building the full row string.

  4. 4. Print row outer, col inner

    Row-wise log: for (let row = 1; row <= rows; row++) for (let col = 1; col <= row; col++).

  5. 5. Dry-Run rows = 5

    Trace five rows on paper before coding the full 10-row demo.

Pro Tip: if the output is a vertical list of single numbers, you almost certainly put console.log(line) inside the inner loop.

Common Pitfalls

Mistakes that commonly break column-wise number triangle patterns.

  1. 1. console.log Inside Inner Loop

    Each number lands on its own line — you get a column, not a triangle.

    → Use line += tri[row][col]; call console.log(line) only after the row loop finishes.

  2. 2. Wrong Fill Loop Nesting

    Using row outer during fill instead of col gives the standard consecutive triangle.

    → Use for (let col = 1; col <= rows; col++) as the fill outer loop.

  3. 3. Forgetting Spaces Between Values

    Output runs together like 2610 instead of 2 6 and 3 7 10.

    → Add if (col < row) line += " " between values.

  4. 4. Forgetting Newline After Row

    All numbers print on one long line without row breaks.

    → Add console.log(line) after building each row string.

  5. 5. Unchecked parseInt(prompt())

    Letters or empty input return NaN when parseInt(prompt()) is unchecked.

    → Validate with Number.isFinite(rows) and re-prompt on failure.

Edge Cases

Check these inputs before calling the solution done.

rows = 1

Single row

Output is just 1 — the right loop does not run.

rows = 0

Empty output

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

Negative

rows < 0

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

rows = 5

Compact trace

Peak row 5 produces 9 lines — good for dry-runs.

Bad input

Non-numeric input

Unchecked parseInt(prompt()) returns NaN — use Number.isFinite.

Large rows

Wide output

Row 9 scans 17 character positions — total work grows as O(n²).

🎯 Practice Problems

Try these variations to lock in the pattern.

1. Compare with Program 54

  • Program 54 uses diagonal conditions with spaces
  • Program 55 uses a 2D array filled column-wise

2. Fill row-wise instead

  • Swap to row outer during fill — get 1, 2 3, 4 5 6
  • Compare output with the column-wise version

3. Next in series

  • Continue with Program 56
  • Build on column-wise number patterns

4. Fixed-width formatting

  • Use String(tri[row][col]).padStart(3) for alignment when rows exceed 9
  • Try rows = 10 where values reach 55

Notes

  • Two phases. Fill: col outer, row = col..rows. Print: row outer, col = 1..row.
  • line += ... builds the row; console.log(line) advances — call it after the row string is complete.
  • Validate rows > 0 for interactive programs; largest value = rows*(rows+1)/2.
  • Total values = n(n+1)/2 — fill and print each visit every cell once.

Quick Takeaway: fill tri[row][col] = num; num++ column-wise, build each row from tri[row][col] with spaces, then console.log(line).

⏱️ Time and Space Complexity

ProgramTimeExtra space
Fill + log loops (Examples 1–3)O(n²)O(n²) for the array
Total valuesn(n+1)/2Largest value also n(n+1)/2
Wrap Up

🎉 Conclusion

The column-wise number triangle is a natural follow-up to Program 54: store values in a 2D array, fill column-wise, then log row-wise for the distinctive jump pattern. Master the fixed-rows version, then try user input and the compact 3-row trace.

Practice the three examples above, then continue to Program 56 for the next pattern in the series.

Fill order (column first) creates the jumps — row 2 shows 2 6, not 2 3.

💡 Best Practices

✅ Do

  • Declare const tri = Array.from({ length: rows + 1 }, () => Array(rows + 1).fill(0));
  • Fill: for (let col = 1; col <= rows; col++) for (let row = col; row <= rows; row++) tri[row][col] = num++;
  • Log: for (let row = 1; row <= rows; row++) for (let col = 1; col <= row; col++)
  • Add spaces with if (col < row) line += " "
  • Use Number.isFinite for user input

❌ Don’t

  • Swap fill loop nesting — you get the standard consecutive triangle
  • Print during fill without storing — hard to get column-wise output
  • Call console.log(line) inside the row inner loop
  • Ignore bad console input in user-facing demos
  • Skip the rows = 3 dry-run before coding rows = 5

Key Takeaways

Knowledge Unlocked

Five things to remember about this column-wise triangle

Print the jump pattern the beginner-friendly way.

5
Core concepts
02

2D array

tri[row][col]

Code
03

Fill

col outer, row inner

Code
04

Log

row outer, col inner

Logic
O 05

Complexity

n(n+1)/2 values

Analysis

❓ Frequently Asked Questions

Because the triangle is filled column-wise: after finishing column 1 (1..5), the next available number is 6 for column 2.
Column-wise filling creates the distinctive jumps (6, 10, 13). Row-wise logging displays the familiar triangle shape.
For rows=5: 1; 2 6; 3 7 10; 4 8 11 13; 5 9 12 14 15 — numbers increase within each column during fill.
Program 54 uses diagonal conditions with spaces. Program 55 uses a 2D array filled column-wise then logged row-wise.
Not strictly, but it keeps fill order and log order separate — much clearer for beginners.
Yes. Loop rows first and you get the standard 1, 2 3, 4 5 6 triangle — compare both approaches.
O(n²) for n rows because total filled/logged values equal n(n+1)/2.
For rows=n, the largest number is n(n+1)/2 — the triangular number of cells.
Use parseInt with Number.isFinite. Bare parseInt(prompt()) returns NaN on bad input.
One row logs a single 1 — fill and log loops each run once.

Did you Know? 🔊

Numbers are filled column-wise into a 2D array — column 1 gets 1..n, column 2 gets the next block, and so on — then logged row-wise. Total values = n(n+1)/2, so O(n²).

Continue to Program 56

Move on to the next pattern in the JavaScript number-pattern series.

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