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.

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.
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.
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.
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.
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.
rows = 3..9
Pick row count and draw the column-wise triangle in the browser.
Complexity
Total values = 1+2+…+n = n(n+1)/2 — classic triangular number complexity.
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).
It bridges Program 54’s conditional patterns to 2D array storage — teaching fill order vs log order as separate steps.
Outer col, inner row = col..rows.
Outer row, inner col = 1..row.
Program 54 uses diagonal conditions; Program 55 uses a 2D array with column-wise filling.
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).
Given row count rows = 5, fill a triangle column-wise with increasing numbers, then log row-wise.
// rows = 5
// 1
// 2 6
// 3 7 10
// 4 8 11 13
// 5 9 12 14 15 | Item | Type | Description |
|---|---|---|
rows | number | Triangle height — row i logs i values. |
tri[row][col] | 2D number array | 2D array storing filled values — 1-based indexing. |
num | number | Running counter incremented during column-wise fill. |
col (fill outer) | number | Column index — runs 1 to rows. |
row (fill inner) | number | Runs col..rows for each column during fill. |
| Max value | number | Largest logged number = rows*(rows+1)/2. |
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 | Idea | Best for |
|---|---|---|
| 2D array + column fill | Fill column-wise, log row-wise | This distinctive jump pattern |
| Row-wise fill | Standard 1, 2 3, 4 5 6 triangle | Comparison / simpler output |
| User-input rows | parseInt(prompt()) | Flexible triangle size |
| Compact trace | rows = 3 on paper first | Quick dry-runs (6 cells total) |
| Fixed-width print | String(val).padStart(3) in line building | Alignment when rows exceed 9 |
| Goal | Pattern |
|---|---|
| Declare array | const tri = Array.from({ length: rows + 1 }, () => Array(rows + 1).fill(0)); |
| Fill column-wise | for (let col = 1; col <= rows; col++) for (let row = col; row <= rows; row++) tri[row][col] = num++; |
| Log row-wise | 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); } |
| Add spacing | if (col < row) line += " " between values |
| End row | console.log(line); |
| Program 54 contrast | Program 54 uses diagonal conditions; Program 55 uses 2D array column fill |
Same column-wise triangle — three ways to set row count and trace the fill order.
rows = 5Hard-coded height for demos (15 values)
parseInt(prompt())Read row count from console
rows = 36-cell triangle for paper tracing
col outerColumn-wise assignment
row outerRow-wise display
Reach for this pattern when teaching 2D arrays, fill order vs log order, and triangular number sequences.
Natural follow-up after Program 54’s diamond — introduces 2D array storage and column-wise filling.
Fill in one order, print in another — a pattern used in matrices, grids, and game boards.
Total cells = n(n+1)/2 — links loops to the triangular number formula.
Compare column-wise fill with the next pattern in the series.
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.
Choose row count between 3 and 9 and draw the column-wise number triangle in the browser.
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.
Fill a 5-row triangle column-wise into a 2D array, then log row-wise with spaces.
rows = 5Hard-coded row count — fill with col outer and row = col..rows inner, then log with row outer and col = 1..row inner.
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);
} 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.
Read row count with prompt() and Number.isFinite validation.
Read rows with prompt() and validate the result.
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);
}
} Same column-fill then row-log core as Example 1; only the source of rows changes from a literal to user input.
Smaller row count for quick tracing on paper or in interviews.
rows = 3Use rows = 3 to trace column fill (6 cells) before scaling to 5 rows.
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);
} 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.
const tri = Array.from({ length: rows + 1 }, () => Array(rows + 1).fill(0)); — 1-based indexing for rows and columns.
for (let col = 1; col <= rows; col++) for (let row = col; row <= rows; row++) tri[row][col] = num++;.
for (let row = 1; row <= rows; row++) — build each line from stored values with spaces, then console.log(line).
Row 2 shows 2 6 because column 1 has 2 and column 2 has 6 at row 2 — not consecutive fill order.
Total values = n(n+1)/2 — O(n²) time, O(n²) array space.
rows = 5Trace column-wise fill assignments and the resulting row output.
| Column | Fills rows | Values assigned |
|---|---|---|
1 | 1..5 | 1, 2, 3, 4, 5 |
2 | 2..5 | 6, 7, 8, 9 |
3 | 3..5 | 10, 11, 12 |
4 | 4..5 | 13, 14 |
5 | 5 | 15 |
row | Columns logged | Row output |
|---|---|---|
1 | col 1 | 1 |
2 | col 1–2 | 2 6 |
3 | col 1–3 | 3 7 10 |
4 | col 1–4 | 4 8 11 13 |
5 | col 1–5 | 5 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.
Where this tiny pattern (and its loop structure) shows up beyond the homework prompt.
Column-wise fill then row-wise log — two distinct loop phases.
Example: trace the fill table and row output table in the walkthrough.
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.
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.
Total cells = n(n+1)/2 — the nth triangular number.
Example: Peak row 10 fills 55 cells — largest value is 55.
Growing inner bound makes O(n²) concrete — count prints for n rows.
Example: Peak row 5 fills 15 cells — see the walkthrough table.
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.
Why this pattern earns a permanent spot in beginner JavaScript courses.
Swapping fill and print loop nesting without an array produces scrambled output.
Column-wise fill teaches real 2D array usage — not abstract loop drill.
Change rows, use fixed-width format, or switch to full rectangular table.
Streaming output needs no storage beyond loop counters.
Pro Tip: trace rows = 3 on paper — 6 cells, output 1 / 2 4 / 3 5 6.
Small habits that keep number-pattern code clean.
Column-wise fill: for (let col = 1; col <= rows; col++) for (let row = col; row <= rows; row++).
Number.isFiniteAvoid using uninitialized rows when the user types letters instead of a number.
Only call console.log(line) after building the full row string.
Row-wise log: for (let row = 1; row <= rows; row++) for (let col = 1; col <= row; col++).
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.
Mistakes that commonly break column-wise number triangle patterns.
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.
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.
Output runs together like 2610 instead of 2 6 and 3 7 10.
→ Add if (col < row) line += " " between values.
All numbers print on one long line without row breaks.
→ Add console.log(line) after building each row string.
Letters or empty input return NaN when parseInt(prompt()) is unchecked.
→ Validate with Number.isFinite(rows) and re-prompt on failure.
Check these inputs before calling the solution done.
Output is just 1 — the right loop does not run.
Outer loop never runs — print nothing or show a message.
rows < 0Treat as invalid; re-prompt instead of silent empty output.
Peak row 5 produces 9 lines — good for dry-runs.
Unchecked parseInt(prompt()) returns NaN — use Number.isFinite.
Row 9 scans 17 character positions — total work grows as O(n²).
Try these variations to lock in the pattern.
String(tri[row][col]).padStart(3) for alignment when rows exceed 9col 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.rows > 0 for interactive programs; largest value = rows*(rows+1)/2.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).
| Program | Time | Extra space |
|---|---|---|
| Fill + log loops (Examples 1–3) | O(n²) | O(n²) for the array |
| Total values | n(n+1)/2 | Largest value also n(n+1)/2 |
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.
const tri = Array.from({ length: rows + 1 }, () => Array(rows + 1).fill(0));for (let col = 1; col <= rows; col++) for (let row = col; row <= rows; row++) tri[row][col] = num++;for (let row = 1; row <= rows; row++) for (let col = 1; col <= row; col++)if (col < row) line += " "Number.isFinite for user inputconsole.log(line) inside the row inner looprows = 3 dry-run before coding rows = 5Print the jump pattern the beginner-friendly way.
Fill column-wise, log row-wise
Definitiontri[row][col]
Codecol outer, row inner
Coderow outer, col inner
Logicn(n+1)/2 values
AnalysisNumbers 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²).
Move on to the next pattern in the JavaScript number-pattern series.
12 people found this page helpful