C# Number Triangle Pattern (Reverse Descending)

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

What Is This Pattern?

A reverse descending number triangle prints digits i..1 on each row, with the outer loop counting down so the first row is longest.

Remember
Rule: for i = n..1, print i..1

54321
4321
321
21
1       ← 5 rows

In C# the outer loop runs i = rows..1, the inner loop prints j from i down to 1, then Console.WriteLine() ends the row. Flip the inner loop to j = 1..i for Program 1’s ascending digits on a shrinking triangle.

How to Solve It

One nested-loop idea with two useful variants — packed digits and spaced digits.

MethodIdeaBest for
Nested descending loopsOuter shrinks length; inner prints i..1Learning, interviews, exams
Spaced digitsSame loops; print j + " "Practice variants

Pseudocode

Pseudocode
for i from rows down to 1:
    for j from i down to 1:
        print j (no newline)
    print newline

Cheat sheet

GoalPattern
Shrink each rowfor (i = rows; i >= 1; i--)
Print digits i..1for (j = i; j >= 1; j--) Console.Write(j);
End the rowConsole.WriteLine();
Add spacesConsole.Write(j + " ");
Program 1 shape insteadfor (j = 1; j <= i; j++) Console.Write(j);

Write vs WriteLine

APIEffectUse for
Console.WriteStays on the same lineEach digit j
Console.WriteLineEnds the current lineAfter the inner loop

Live Preview

Change the row count and the reverse descending triangle updates instantly — including the total digit count.

Whole numbers from 1 to 9 (keeps digits single-width). Tap a chip or type a value — the preview redraws as you go.

Live result 5 rows · 15 digits
54321
4321
321
21
1

Worked Walkthrough — rows = 4

Trace each outer-loop value of i and the digits the inner loop prints downward.

iInner jPrinted rowDigits
44..143214
33..13213
22..1212
11..111

Total digits are 4+3+2+1 = 10 — the triangular number n(n+1)/2.

C# Programs

Three complete programs: fixed height, row-count input, and spaced digits. Use View Output for sample results.

Example 1 — Fixed rows = 5

Outer loop shrinks the length; inner loop prints digits i..1.

C#
using System;

namespace MyApp
{
    class Program
    {
        static void Main(string[] args)
        {
            int rows = 5;
            int i, j;

            for (i = rows; i >= 1; i--)
            {
                for (j = i; j >= 1; j--)
                {
                    Console.Write(j);
                }
                Console.WriteLine();
            }
        }
    }
}

How It Works

1. Shrink the count. for (i = rows; i >= 1; i--) yields 5, 4, 3, 2, 1.

2. Print downward. When i = 5, the inner loop prints 54321; when i = 1, just 1.

3. Newline. WriteLine() after the inner loop starts the next shorter row.

Example 2 — User Input

Read the row count at runtime. Prefer int.TryParse in real apps so bad input does not throw.

C#
using System;

namespace MyApp
{
    class Program
    {
        static void Main(string[] args)
        {
            int rows;
            int i, j;

            Console.Write("Enter the number of rows: ");
            if (!int.TryParse(Console.ReadLine(), out rows) || rows < 1)
            {
                Console.WriteLine("Please enter a positive whole number.");
                return;
            }

            for (i = rows; i >= 1; i--)
            {
                for (j = i; j >= 1; j--)
                {
                    Console.Write(j);
                }
                Console.WriteLine();
            }
        }
    }
}

How It Works

1. Validate rows. TryParse rejects non-numeric input; require rows >= 1.

2. Same nested loops. Four rows start at 4321 and end at 1.

Example 3 — Spaced Digits

Same reverse-descending shape — only the print statement adds a space.

C#
using System;

namespace MyApp
{
    class Program
    {
        static void Main(string[] args)
        {
            int rows = 5;
            int i, j;

            for (i = rows; i >= 1; i--)
            {
                for (j = i; j >= 1; j--)
                {
                    Console.Write(j + " ");
                }
                Console.WriteLine();
            }
        }
    }
}

How It Works

1. Same loops. Outer still shrinks; inner still prints i..1.

2. Add gaps. Write(j + " ") inserts a space after each digit.

Edge Cases & Pitfalls

Check these before calling the solution done.

ascend j

j = 1..i instead of j = i..1

That prints ascending digits (Program 1). Keep for (j = i; j >= 1; j--).

grow outer

i = 1..rows instead of rows..1

That grows the triangle. Use for (i = rows; i >= 1; i--) so the first row is longest.

WriteLine early

WriteLine(j) inside the inner loop

That puts each digit on its own line. Use Write(j); call WriteLine() only after the row finishes.

rows = 1

Single 1

Output is just 1 — a good sanity check.

rows ≤ 0

Empty output

The outer loop never runs. Validate and prompt again for clearer UX.

Bad input

Convert.ToInt32 throws

Prefer int.TryParse so non-numeric input does not crash the program.

Time and Space Complexity

ProgramTimeExtra space
Packed digits (Examples 1–2)O(n²)O(1)
Spaced digits (Example 3)O(n²)O(1)

There are n rows printing n+(n-1)+…+1 digits, so total work is n(n+1)/2.

Key Takeaways

  • Rule: for i = n..1, print digits i..1 with Write.
  • Count down twice: outer shrinks length; inner reverses the digits.
  • Write vs WriteLine: digits stay on the line; WriteLine advances after each row.
  • Next step: Program 4 left-aligns a descending triangle with leading spaces.

One line: for each length from n down to 1, print i..1 with Write, then WriteLine.

Frequently Asked Questions

The inner loop runs j = i down to 1, so each row prints i, i-1, …, 1.
Because rows = 5 and the outer loop starts with i = rows. The first row prints from 5 down to 1.
Program 2 prints i..rows (left-shifted). Program 3 prints i..1 (reverse descending) with a shrinking outer loop.
Keep the descending outer loop but change the inner loop to j = 1..i (ascending) — that is Program 1’s shape.
Replace 5 with rows in the outer bound — see Example 2.
Use Console.Write(j + " ") instead of Console.Write(j) — see Example 3.
O(n²) for n rows. Total prints are n + (n-1) + … + 1 = n(n+1)/2.
Prefer int.TryParse(Console.ReadLine(), out rows) so bad input does not throw FormatException.
Only one row prints — a single 1.

Did you know?

This pattern prints each row in descending order from i down to 1. The outer loop shrinks the row length while the inner loop counts downward — producing 54321, 4321, 321, and so on.

Next: Left-Aligned Descending Triangle

Keep descending digits, but pad with leading spaces for right-side alignment.

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