C Number Triangle Pattern (Bidirectional)

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

What Is This Pattern?

A bidirectional number triangle prints one repeated digit per row while the row length shrinks — digits climb (1, 2, 3), then mirror down (2, 1) on the last rows.

Remember
Rule: row i length = rows - i + 1
      digit = i if i < rows - 1, else rows + 1 - i

11111
2222
333
22
1         ← rows = 5

Two ideas together: a shrinking inner loop (j = i..rows) and a conditional digit map. Follows the centered pyramid in Program 24; next is Program 26.

How to Solve It

Start with fixed rows = 5 and an if/else map, then generalize with a ternary — optionally space the digits.

MethodIdeaBest for
Shrink + if/else mapInner j = i..rows; digit rises then mirrorsLearning, interviews, exams
Spaced digitsSame loops; printf("%d ", val)Easier reading once the core clicks

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 (no newline)
    print newline

Cheat sheet

GoalPattern
Walk each rowfor (i = 1; i <= rows; i++)
Shrink the rowfor (j = i; j <= rows; j++)
Pick the digitval = (i < rows - 1) ? i : (rows + 1 - i);
Print the digitprintf("%d", val);
End the rowprintf("\n");
Spaced variantprintf("%d ", val);

Printing Numbers vs Starting a New Line

APIEffectUse for
printf("%d", val)Stays on the same lineEach repeated digit
printf("\n")Ends the current lineAfter the inner loop

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

Live Preview

Change the row count and the bidirectional triangle updates instantly — including the triangular digit total.

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

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

Worked Walkthrough — rows = 5

Trace each outer-loop value of i, the mapped digit, and how many times the inner loop runs.

ivalInner jLengthPrinted row
111..5511111
222..542222
333..53333
42 (6 - 4)4..5222
51 (6 - 5)5..511

Total digit prints: 5 + 4 + 3 + 2 + 1 = 15 = 5×6/2. That triangular sum is why time is O(n²).

C Programs

Three complete programs: fixed rows, scanf input, and a spaced-digits variant. Use View Output to reveal sample results.

Example 1 — Fixed rows = 5

Hard-coded height — shrinking inner loop with an if/else digit map.

C
#include <stdio.h>

int main(void)
{
    int i, j;

    for (i = 1; i <= 5; i++)
    {
        for (j = i; j <= 5; j++)
        {
            if (i < 4)
                printf("%d", i);
            else
                printf("%d", 6 - i);
        }
        printf("\n");
    }

    return 0;
}

How It Works

1. Outer loop picks the row. i runs from 1 to 5.

2. Inner loop shrinks the length. j runs from i to 5 — five digits, then four, then three, and so on.

3. Map the digit. While i < 4, print i; otherwise print 6 - i (so row 4 → 2, row 5 → 1).

4. Break the line. printf("\n") after the inner loop starts the next (shorter) row.

Example 2 — User Input Version

Read rows with scanf. Use a ternary so the digit map works for any height.

C
#include <stdio.h>

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

    printf("Enter rows: ");
    scanf("%d", &rows);

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

        for (j = i; j <= rows; j++)
            printf("%d", val);

        printf("\n");
    }

    return 0;
}

How It Works

1. Prompt and read. Ask for a row count, then store it with scanf("%d", &rows).

2. Compute val once per row. (i < rows - 1) ? i : (rows + 1 - i) generalizes the if/else from Example 1.

3. Same shrinking core. Print val from j = i to rows, then printf("\n").

4. Safer input tip. Unchecked scanf leaves rows uninitialized on bad input. Prefer:

Safer input
if (scanf("%d", &rows) != 1 || rows < 1)
{
    printf("Enter a positive whole number.\n");
    return 1;
}

Example 3 — Spaced digits

Keep the same loops; print each digit followed by a space for easier reading.

C
#include <stdio.h>

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

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

        for (j = i; j <= rows; j++)
            printf("%d ", val);

        printf("\n");
    }

    return 0;
}

How It Works

1. Same structure. Outer countdown of length and digit mapping are unchanged.

2. Add a trailing space. Only the print changes — printf("%d ", val) instead of printf("%d", val).

3. Learn the compact form first. Use Examples 1–2 for the classic no-space triangle; treat spacing as a polish option.

Edge Cases & Pitfalls

Check these before calling the solution done.

j = 1

Rectangle, not triangle

If the inner loop starts at 1 instead of i, every row has rows digits. Use for (j = i; j <= rows; j++).

always i

No mirror

Printing i on every row gives 11111, 2222, 333, 44, 5 — missing the bidirectional drop. Keep the rows + 1 - i branch for the last two rows.

\n inside

Column of digits

If printf("\n") is inside the inner loop, each digit lands on its own line. Call the newline only after the inner loop.

hard-coded 4

Breaks for other sizes

if (i < 4) and 6 - i only fit rows = 5. Prefer the ternary with rows (Example 2) for any height.

rows = 1

Single digit

Output is just 1 — a good sanity check.

scanf

Check the return value

If scanf fails, rows may be uninitialized — always test scanf(...) == 1.

Time and Space Complexity

ProgramTimeExtra space
Fixed / input (Examples 1–2)O(rows²)O(1)
Spaced digits (Example 3)O(rows²)O(1)

Total digits = n + (n - 1) + … + 1 = n(n + 1)/2 — quadratic in n.

Key Takeaways

  • Rule: shrink with j = i..rows; digit rises then mirrors with rows + 1 - i.
  • Map once per row: compute val before the inner loop, then just print it.
  • Break the row: call printf("\n") only after the inner loop.
  • Complexity: O(n²) time from the triangular digit count; O(1) extra space.

One line: for each i, set val, print it from j = i to rows, then printf("\n").

Frequently Asked Questions

For i = 5 and rows = 5, the condition i < rows - 1 is false, so the program prints rows + 1 - i = 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.
printf("%d", val) repeats the digit on the same line. printf("\n") ends the row after the inner loop finishes.
A single inner loop with a digit mapping keeps the shrinking row logic in one place.
Replace 5 with rows and use val = (i < rows - 1) ? i : (rows + 1 - i) — see Example 2.
O(n²) for n rows because total prints are triangular (n + (n-1) + … + 1).
Check scanf's return value: if (scanf("%d", &rows) != 1) handle bad input. Unchecked scanf leaves rows uninitialized on failure.

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 early rows, then switches to rows + 1 - i to produce 22 and 1.

Next: Diagonal Asterisk Pattern

Place asterisks on a diagonal inside a number grid.

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