C++ Number Triangle Pattern (Bidirectional)

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

What Is This Pattern?

A bidirectional number triangle repeats one digit per row while the row shortens. Digits rise (1, 2, 3) then mirror down (2, 1).

Remember
Rule: for i from 1 to rows
        val = i if i < rows - 1
              else rows + 1 - i
        print val, (rows - i + 1) times

11111
2222
333
22
1     ← rows = 5

Follows the centered continuous pyramid in Program 24; next is the diagonal asterisk pattern in Program 26.

How to Solve It

Outer loop grows i. Inner loop starts at i (shrinking). Map the digit with if/else or a ternary.

MethodIdeaBest for
If/else mappingPrint i while i < rows - 1; else print rows + 1 - iLearning, interviews, exams
Ternary valval = (i < rows - 1) ? i : (rows + 1 - i);Same logic in one line

Pseudocode

Pseudocode
for i from 1 to rows:
    if i < rows - 1:
        val = i
    else:
        val = rows + 1 - i
    for j from i to rows:
        print val
    print newline

Cheat sheet

GoalPattern
Walk rowsfor (i = 1; i <= rows; i++)
Shrink lengthfor (j = i; j <= rows; j++)
Pick digitval = (i < rows - 1) ? i : (rows + 1 - i);
Print digitcout << val;
End of rowcout << "\n";

Printing Numbers vs Starting a New Line

APIEffectUse for
cout << valStays on the same lineEach repeated digit on the row
cout << "\n"Ends the current lineAfter the inner loop finishes

Print digits without a newline, then end the row once.

Live Preview

Change the row count and the bidirectional triangle updates instantly — capped at 9 for readable demos.

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

Live result rows = 5 · 15 digits
11111
2222
333
22
1

Worked Walkthrough — rows = 5

Trace how shrinking length and the digit map build each row.

ivalCountPrints
11511111
2242222
333333
42222
5111

Total digits = n + (n-1) + … + 1 = n(n+1)/2 → O(n²). Mirror starts when i >= rows - 1.

C++ Programs

Three complete programs: fixed rows = 5, cin input, and a compact rows = 3 demo. Use View Output to reveal sample results.

Example 1 — Fixed rows = 5

Hard-coded height — shrink with j = i..5; map the digit with if/else.

C++
#include <iostream>
using namespace std;

int main()
{
    int rows = 5;
    int i, j;

    for (i = 1; i <= rows; i++)
    {
        for (j = i; j <= rows; j++)
        {
            if (i < rows - 1)
                cout << i;
            else
                cout << rows + 1 - i;
        }
        cout << "\n";
    }

    return 0;
}

How It Works

1. Outer walks rows. i is both the row index and the early-row digit.

2. Inner shrinks. for (j = i; j <= rows; j++) prints fewer digits each line.

3. Mirror late rows. When i >= rows - 1, print rows + 1 - i instead of i.

Example 2 — User Input Rows

Read rows with cin, validate, then use a ternary for the digit map.

C++
#include <iostream>
using namespace std;

int main()
{
    int rows;
    int i, j, val;

    cout << "Enter rows: ";
    if (!(cin >> rows) || rows <= 0)
    {
        cout << "Please enter a positive integer.\n";
        return 1;
    }

    for (i = 1; i <= rows; i++)
    {
        val = (i < rows - 1) ? i : (rows + 1 - i);

        for (j = i; j <= rows; j++)
            cout << val;

        cout << "\n";
    }

    return 0;
}

How It Works

1. Prompt and validate. Reject failed reads and non-positive values before printing.

2. Same core. Ternary digit map + shrinking loop matches Example 1 — only rows comes from the user.

3. Safer input tip. Cap demos for readable output:

Safer input
if (!(cin >> rows) || rows < 1 || rows > 9)
{
    cout << "Enter a whole number from 1 to 9.\n";
    return 1;
}

Example 3 — Compact rows = 3

Same structure with only three rows — easy to confirm rise then mirror.

C++
#include <iostream>
using namespace std;

int main()
{
    int rows = 3;
    int i, j, val;

    for (i = 1; i <= rows; i++)
    {
        val = (i < rows - 1) ? i : (rows + 1 - i);

        for (j = i; j <= rows; j++)
            cout << val;

        cout << "\n";
    }

    return 0;
}

How It Works

1. Three rows. i = 1 → 111; i = 2 → 22; i = 3 → 1.

2. Trace on paper. If you always print i, the last rows become 22/3 instead of mirroring down.

3. Scale up next. Once the small demo is clear, use Examples 1–2 for five rows or user input.

Edge Cases & Pitfalls

Check these before calling the solution done.

no mirror

Always printing i

Skipping the else branch makes late rows print 444/5 instead of 22/1. Keep the rows + 1 - i map.

j = 1

Wrong inner start

Starting at j = 1 keeps every row full width. For shrinking rows use j = i.

hard-code

Fixed 4 and 6

Hard-coding i < 4 and 6 - i only works for rows = 5. Prefer rows - 1 and rows + 1 - i.

\n inside

Broken rows

If cout << "\n" sits inside the inner loop, each digit lands on its own line. Call it only after the row finishes.

rows = 1

Single digit

Output is just 1 — a good sanity check for input validation.

cin

Check the stream

Validate cin >> rows before looping — a failed read leaves rows unset or stale.

Time and Space Complexity

ProgramTimeExtra space
Fixed / input (Examples 1–2)O(n²)O(1)
Compact rows = 3 (Example 3)O(n²)O(1)

Total digits printed = n + (n-1) + … + 1 = n(n+1)/2 → O(n²) time. Only a few loop variables are needed.

Key Takeaways

  • Shrink with j = i: each row prints rows - i + 1 digits.
  • Rise then mirror: use i early, then rows + 1 - i for the last rows.
  • Break the row: cout << val in the inner loop; cout << "\n" after it.
  • Complexity: O(n²) time from n(n+1)/2 digits; O(1) extra space.

One line: for each row i, pick the mapped digit, print it rows - i + 1 times, then newline.

Frequently Asked Questions

A bidirectional shrinking triangle: for rows=5 you get 11111 / 2222 / 333 / 22 / 1 — repeated digits that rise then mirror down while each row shortens.
For i = 5, the condition i < rows - 1 is false, so the program prints rows + 1 - i which becomes 1.
Because the inner loop runs from j = i to rows. As i increases, the inner loop executes fewer times.
Digits rise (1, 2, 3) on early rows then mirror down (2, 1) on the last rows via the rows + 1 - i mapping.
cout << val repeats the digit on the same line. cout << "\n" ends the row after the inner loop finishes.
Use val = (i < rows - 1) ? i : (rows + 1 - i) instead of hard-coding 4 and 6.
After prompting, use if (!(cin >> rows) || rows <= 0) to reject bad input before printing.
O(n²) for n rows because total prints are n+(n-1)+…+1 = n(n+1)/2.

Did you know?

This pattern prints repeated digits per row. The inner loop runs from j = i to rows, shrinking each row. The row digit is i for the first half, then switches to rows + 1 - i to produce 22 and 1.

Next: Diagonal Asterisk Pattern

Continue with descending numbers and a diagonal of asterisks.

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