Column-Wise Number Triangle Pattern in C#

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

What You’ll Learn

Program 55 prints a column-wise number triangle: fill a 2D array column by column with increasing numbers, then print row by row — a natural step after Program 54’s mirror diagonal diamond. This tutorial covers column-wise filling, row-wise printing, a live preview, worked C# 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 print each row left to right.

2D Array

tri[row, col]

int[,] tri = new int[rows+1, rows+1] stores values so fill order and print order can differ.

Fill Loop

col outer, row inner

for (col = 1..rows) for (row = col..rows) tri[row,col] = num++ — column-wise assignment.

Print Loop

row outer, col inner

for (row = 1..rows) for (col = 1..row) Console.Write(tri[row,col]) — 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 C# declare a 2D array, fill with nested loops (col outer, row inner), then print 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 print 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++ column-wise, then print tri[row,col] row-wise with spaces between values.

📝 Problem & Approach

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

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

Inputs & Outputs

ItemTypeDescription
rowsintTriangle height — row i prints i values.
tri[row, col]int[,]2D array storing filled values — 1-based indexing.
numintRunning counter incremented during column-wise fill.
col (fill outer)intColumn index — runs 1 to rows.
row (fill inner)intRuns col..rows for each column during fill.
Max valueintLargest printed 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:
    for col from 1 to row:
        print tri[row][col]
    print newline

Approach comparison

ApproachIdeaBest for
2D array + column fillFill column-wise, print row-wiseThis distinctive jump pattern
Row-wise fillStandard 1, 2 3, 4 5 6 triangleComparison / simpler output
User-input rowsint.TryParse(...)Flexible triangle size
Compact tracerows = 3 on paper firstQuick dry-runs (6 cells total)
Fixed-width printConsole.Write($"{val,3}")Alignment when rows exceed 9

⚡ Quick Reference

GoalPattern
Declare arrayint[,] tri = new int[rows + 1, rows + 1];
Fill column-wisefor (col = 1; col <= rows; col++) for (row = col; row <= rows; row++) tri[row,col] = num++;
Print row-wisefor (row = 1; row <= rows; row++) for (col = 1; col <= row; col++) Console.Write(tri[row,col]);
Add spacingif (col < row) Console.Write(" "); between values
End rowConsole.WriteLine();
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
TryParse

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 print 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/print 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 C# programs — fixed rows, user input, and a compact trace demo. Click View Output to reveal sample console results.

📚 Getting Started

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

Example 1 — Fixed rows = 5

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

C#
using System;

namespace MyApp
{
    class Program
    {
        static void Main(string[] args)
        {
            int rows = 5;
            int[,] tri = new int[rows + 1, rows + 1];

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

            for (int row = 1; row <= rows; row++)
            {
                for (int col = 1; col <= row; col++)
                {
                    Console.Write(tri[row, col]);
                    if (col < row) Console.Write(" ");
                }
                Console.WriteLine();
            }
        }
    }
}

How It Works

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

📈 User Input

Read row count from the console with safe parsing.

Example 2 — User Input Rows

Read rows from the console with int.TryParse — reject invalid input gracefully.

C#
using System;

namespace MyApp
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.Write("Enter the number of rows: ");
            if (!int.TryParse(Console.ReadLine(), out int rows) || rows <= 0)
            {
                Console.WriteLine("Please enter a positive integer.");
                return;
            }
            int[,] tri = new int[rows + 1, rows + 1];

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

            for (int row = 1; row <= rows; row++)
            {
                for (int col = 1; col <= row; col++)
                {
                    Console.Write(tri[row, col]);
                    if (col < row) Console.Write(" ");
                }
                Console.WriteLine();
            }
        }
    }
}

How It Works

Same column-fill then row-print 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.

C#
using System;

namespace MyApp
{
    class Program
    {
        static void Main(string[] args)
        {
            int rows = 3;
            int[,] tri = new int[rows + 1, rows + 1];

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

            for (int row = 1; row <= rows; row++)
            {
                for (int col = 1; col <= row; col++)
                {
                    Console.Write(tri[row, col]);
                    if (col < row) Console.Write(" ");
                }
                Console.WriteLine();
            }
        }
    }
}

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

int[,] tri = new int[rows + 1, rows + 1]; — 1-based indexing for rows and columns.

Setup
2

Fill column-wise

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

Fill
3

Print row-wise

for (row = 1; row <= rows; row++) for (col = 1; col <= row; col++) — print stored values with spaces.

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 printedRow 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 print — 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. Console Formatting Drills

Practice Write vs WriteLine with multiple values per row.

Example: put WriteLine 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 TryParse and positive-row checks.

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 C# 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 (col = 1; col <= rows; col++) for (row = col; row <= rows; row++).

  2. 2. Prefer TryParse

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

  3. 3. WriteLine After Both Inner Loops

    Only call WriteLine() after both inner loops finish the row.

  4. 4. Print row outer, col inner

    Row-wise print: for (row = 1; row <= rows; row++) for (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 WriteLine inside the inner loop.

Common Pitfalls

Mistakes that commonly break column-wise number triangle patterns.

  1. 1. WriteLine Inside Inner Loop

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

    → Use Console.Write(tri[row,col]); WriteLine only after the print inner loop.

  2. 2. Wrong Fill Loop Nesting

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

    → Use for (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) Console.Write(" "); between values.

  4. 4. Forgetting WriteLine After Row

    All numbers print on one long line without row breaks.

    → Add Console.WriteLine() after both inner loops complete.

  5. 5. Blind Convert.ToInt32

    Letters or empty input throw FormatException.

    → Prefer int.TryParse 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 ReadLine

Convert.ToInt32 throws — use TryParse.

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 Console.Write($"{tri[row,col],3}") for alignment
  • Try rows = 10 where values reach 55

Notes

  • Two phases. Fill: col outer, row = col..rows. Print: row outer, col = 1..row.
  • Console.Write stays on the line; WriteLine advances — call it after the print inner loop finishes each row.
  • 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++ column-wise, print tri[row,col] row-wise with spaces, then WriteLine().

⏱️ Time and Space Complexity

ProgramTimeExtra space
Fill + print 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 print 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 int[,] tri = new int[rows + 1, rows + 1]
  • Fill: for (col = 1; col <= rows; col++) for (row = col; row <= rows; row++) tri[row,col] = num++
  • Print: for (row = 1; row <= rows; row++) for (col = 1; col <= row; col++)
  • Add spaces with if (col < row) Console.Write(" ")
  • Use int.TryParse 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 WriteLine inside the print 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

Print

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 printing 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 printed row-wise.
Not strictly, but it keeps fill order and print 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/printed values equal n(n+1)/2.
For rows=n, the largest number is n(n+1)/2 — the triangular number of cells.
Prefer int.TryParse(Console.ReadLine(), out rows) so bad input does not throw FormatException.
One row prints a single 1 — fill and print 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 printed row-wise. Total values = n(n+1)/2, so O(n²).

Continue to Program 56

Move on to the next pattern in the C# 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