Bidirectional Number Triangle in C

Beginner
⏱️ 8 min read
📚 Updated: Aug 2026
🎯 3 Code Examples
🚀 Live Preview
If/Else Mapping

What You’ll Learn

The bidirectional number triangle prints 11111, 2222, 333, 22, 1 — a natural step after the centered pyramid in Program 24. This tutorial covers shrinking rows, if/else digit mapping, a live preview, algorithm steps, worked C examples, edge cases, and complexity.

Shape Rule

Shrinking rows

Row 1 prints five 1s, row 2 prints four 2s, row 5 prints a single 1.

Outer Loop

i = 1..rows

for (i = 1; i <= rows; i++) walks each row top to bottom.

Shrinking Inner Loop

j = i..rows

for (j = i; j <= rows; j++) prints fewer digits as i grows.

If/Else Mapping

6 - i mirror

i < 4 prints i; else prints 6 - i for rows 4 and 5.

Live Preview

3–9 rows

Pick a row count and draw the bidirectional triangle instantly in the browser.

O(n²)

Complexity

Total prints are triangular — scales as for n rows.

Introduction

A bidirectional number triangle prints repeated digits per row with shrinking length — digits rise then mirror down. With rows = 5, the output is 11111, 2222, 333, 22, 1.

In C you use an outer loop for rows, a shrinking inner loop j = i..rows, and an if/else to pick which digit to repeat.

Why it matters?

It combines shrinking inner loops with conditional mapping — a step up from Program 24’s spacing logic.

Key Highlights

Shrinking rows

j = i..rows — each row prints fewer digits.

Rising digits

i < 4 repeats 1, 2, 3.

Mirror down

6 - i produces 2 and 1 on last rows.

Series Foundation

Follow Program 24; continue to Program 26 (diagonal asterisk) next.

In short: for each i, repeat a digit (rows - i + 1) times — use i when i < rows - 1, else rows + 1 - i.

📝 Problem & Approach

Given a positive integer rows (e.g. 5), print a shrinking triangle where each row repeats one digit — rising on early rows, mirroring down on the last rows.

c
// rows = 5 (conceptual shape)
// 11111
// 2222
// 333
// 22
// 1

Inputs & Outputs

ItemTypeDescription
rowsintNumber of rows — outer loop runs from 1 to rows.
iintOuter loop — current row number (also the digit for early rows).
jintInner loop — j = i..rows controls shrinking row length.
valintDigit to repeat — i or rows + 1 - i via if/else.

Minimal workflow

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

Approach comparison

ApproachIdeaBest for
If/else mapping11111, 2222, … 1Learning and interviews
User-input rowsscanf("%d", &rows);Flexible console programs
Ternary valval = (i < rows - 1) ? i : (rows + 1 - i)Compact generalized version

⚡ Quick Reference

GoalPattern
Walk rowsfor (i = 1; i <= rows; i++)
Shrink inner loopfor (j = i; j <= rows; j++)
Pick digit (fixed)if (i < 4) printf("%d", i); else printf("%d", 6 - i);
Pick digit (general)val = (i < rows - 1) ? i : (rows + 1 - i);
End the rowprintf("\n");
User inputscanf("%d", &rows);

📋 Fixed rows vs User Input vs Spaced Output

Same bidirectional triangle — different ways to control rows and formatting.

Outer loop
i = 1..rows

One row per outer iteration

Inner loop
j = i..rows

Shrinking row length each row

Mapping
6 - i

Mirrors digits on last rows

Learning tip
if/else

Compute val once per row, not per column

Context

When This Pattern Shows Up

Reach for this pattern when teaching shrinking inner loops, conditional digit mapping, and bidirectional output.

  1. Post pyramid exercise

    Natural follow-up after Program 24 — introduces if/else mapping and shrinking rows.

  2. Nested-loop warm-up

    Outer/inner bound practice with an immediate visual check.

  3. Console I/O practice

    Combine loops with scanf for a flexible row count.

  4. Gateway to variants

    Compare Program 24 (centered pyramid) and Program 26 (diagonal asterisk) next.

  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 nested loops, output sequencing, and O(n²) thinking.

🔮 Live Preview

Choose a row count between 3 and 9 and draw the bidirectional 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 spaced output variant. Click View Output to reveal sample console results.

📚 Getting Started

Print five rows of the bidirectional triangle with if/else mapping.

Example 1 — Fixed rows = 5

Hard-coded row count — ideal for first demos and screenshots.

c
#include <stdio.h>

int main() {
    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

When i = 1, print five 1s — output 11111. When i = 3, print three 3s — output 333. When i = 4, the else branch prints 6 - 4 = 2 twice — output 22. When i = 5, print 6 - 5 = 1 once.

📈 User Input

Read the row count with scanf instead of hard-coding 5.

Example 2 — User Input

Read rows with scanf("%d", &rows); use a ternary to generalize the digit mapping.

c
#include <stdio.h>

int main() {
    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

Same shrinking inner loop as Example 1; the ternary (i < rows - 1) ? i : (rows + 1 - i) generalizes the if/else mapping for any row count. Non-numeric input leaves rows unset if you ignore scanf’s return value — always check it in safer labs.

⚡ Spaced Output

Add a space between repeated digits for easier reading.

Example 3 — Spaced Digits

Keep rows = 5 but print each digit followed by a space.

c
#include <stdio.h>

int main() {
    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

Only the print statement changes — printf("%d ", val) instead of printf("%d", val). The shrinking loop and digit mapping stay the same.

🧠 How the Algorithm Prints Rows

1

Set up

#include <stdio.h> brings in printf / scanf. Set loop variables i, j and rows = 5.

Setup
2

Outer loop walks rows

for (i = 1; i <= rows; i++) — one row per iteration.

Row
3

Shrinking inner loop (j)

for (j = i; j <= rows; j++) — row length shrinks as i grows.

Shrink
4

If/else digit mapping

if (i < 4) prints i; else printf("%d", 6 - i) mirrors down.

Mapping
5

New line

printf("\n") ends the row after the inner loop.

Break
=

Bidirectional triangle complete

Digits rise then mirror down — O(n²) time, O(1) extra memory.

🔎 Worked Walkthrough — rows = 5

Trace each outer-loop value of i, the digit chosen, inner-loop count, and row output.

iDigit (val)Inner loop (j)PrintsRow output
11 (i < 4)1..5 (5 times)511111
222..5 (4 times)42222
333..5 (3 times)3333
42 (6 - i)4..5 (2 times)222
51 (6 - i)5..5 (1 time)11

Prints per row = rows - i + 1 — total prints = n(n+1)/2 for n rows.

Use Cases

Where this tiny pattern (and its loop structure) shows up beyond the homework prompt.

1. Teaching Nested Loops

Clearest visual proof that outer and inner bounds interact.

Example: change j = i to j = 1 and watch rows stop shrinking.

2. Pattern Series Base

Foundation for inverted, pyramid, diamond, and hollow variants.

Example: use rows + 1 - i for a fully symmetric variant.

3. Console Formatting Drills

Practice printf vs row newline without complex math.

Example: put printf("\n") inside the inner loop by mistake.

4. Character Substitution

Swap digits for letters or add spaces once the loop works.

Example: print val + " " for spaced repeated digits.

5. Complexity Intuition

Triangular totals make O(n²) concrete for beginners.

Example: count printed numbers for rows = 5 → 5 + 4 + 3 + 2 + 1 = 15.

6. Input Validation Labs

Pair the pattern with scanf return checks and positive-row checks.

Example: reject max <= 0 and re-prompt.

Pro Tip: when an interviewer asks for patterns, explain the 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

    Wrong bounds show up immediately as a broken staircase.

  2. 2. Minimal Concepts

    Only loops and console output — no arrays or math libraries.

  3. 3. Easy to Extend

    Invert, center, hollow, or change the fill character with small edits.

  4. 4. O(1) Extra Memory

    Streaming output needs no storage beyond loop counters.

Pro Tip: trace the shrinking inner loop on paper for rows = 3 before coding — mapping bugs hide in the 6 - i threshold.

Usage Tips

Small habits that keep number-pattern code clean.

  1. 1. Name Bounds Clearly

    Do not reset val inside the inner loop — compute it once per row.

  2. 2. Prefer scanf

    Check the return value so bad input does not leave rows uninitialized.

  3. 3. Keep printf("\n") Outside

    Only call printf("\n") after the inner loop finishes the row.

  4. 4. Trace i and val on Paper

    Write each i, digit chosen, and print count before coding.

  5. 5. Dry-Run One Small n

    Trace rows = 3 on paper before coding larger demos.

Pro Tip: if the output is a vertical list of single digits per line, you almost certainly put printf("\n") inside the inner loop.

Common Pitfalls

Mistakes that commonly break bidirectional number triangle patterns.

  1. 1. Newline Inside the Inner Loop

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

    → Use printf("%d", val); printf("\n") only after the inner loop.

  2. 2. Recomputing val Inside Inner Loop

    Putting the if/else inside the inner loop works but is wasteful — compute val once per row.

    → Set val before the inner loop, then just printf("%d", val).

  3. 3. Wrong Inner Loop Bound

    Using j = 1 to rows prints full-width rows — no shrinking.

    → Use for (j = i; j <= rows; j++) so each row is shorter.

  4. 4. Wrong Mirror Threshold

    Using i < rows instead of i < rows - 1 skips the mirror on the last row.

    → For generalized code use (i < rows - 1) ? i : (rows + 1 - i).

  5. 5. Unchecked scanf

    Letters or empty input leave rows uninitialized.

    → Check scanf return value and re-prompt on failure.

Edge Cases

Check these inputs before calling the solution done.

rows = 1

Single row

Output is just 1 — one digit, one row.

rows = 0

Empty pattern

Outer loop never runs — print nothing or show a message.

Negative

rows < 0

Treat as invalid; re-prompt instead of silent empty output.

rows = 2

Smallest triangle

Two rows: 11 and 1.

Bad input

Non-numeric scanf input

Unchecked scanf leaves rows unset — check the return value.

Large rows

Large row count

Output grows as n² characters — fine for labs, noisy for huge n.

🎯 Practice Problems

Try these variations to lock in the pattern.

1. Centered pyramid

2. Diagonal asterisk

  • Descending numbers with * on diagonal
  • Continue with Program 26

3. Extract a method

  • Move pattern logic into PrintTriangle(int rows)
  • Call from Main with user input

4. Full mirror mapping

  • Use rows + 1 - i for all rows, not just last two
  • Compare symmetric vs bidirectional output

Notes

  • Shrinking rows. Inner loop j = i..rows — row length = rows - i + 1 digits per row.
  • printf("%d", val) repeats the digit; printf("\n") advances — mix them carefully.
  • Validate rows > 0 for interactive programs; rows = 1 prints a single 1.
  • Compute val once per row outside the inner loop — cleaner and slightly faster.

Quick Takeaway: outer loop i = 1..rows, shrinking inner loop j = i..rows, if/else digit mapping, then printf("\n") after each row.

⏱️ Time and Space Complexity

ProgramTimeExtra space
Nested loops (Examples 1–2)O(n²)O(1)
Spaced output (Example 3)O(n²)O(1)
Wrap Up

🎉 Conclusion

The bidirectional number triangle is a compact lesson in shrinking loops and conditional mapping: repeat a digit per row with j = i..rows, then mirror down with 6 - i. Master the fixed-rows version, then try user input and spaced output.

Practice the three examples above, then continue to Program 26 for the descending pattern with diagonal asterisk.

Compute val once per row — validate rows when reading from the console.

💡 Best Practices

✅ Do

  • Use for (i = 1; i <= rows; i++) in the outer loop
  • Shrink with for (j = i; j <= rows; j++)
  • Compute val once per row before the inner loop
  • Check scanf return value before using rows
  • State O(n²) time when asked about complexity

❌ Don’t

  • Call printf("\n") inside the inner loop
  • Use j = 1 in the inner loop — rows won’t shrink
  • Hard-code 6 - i in generalized code — use rows + 1 - i
  • Recompute the digit mapping on every inner iteration
  • Ignore bad console input in user-facing demos
  • Skip the rows = 1 edge case

Key Takeaways

Knowledge Unlocked

Five things to remember about this triangle pattern

Print the pattern the beginner-friendly way.

5
Core concepts
02

j = i..rows

Shrinking rows

Code
+ 03

if/else

6 - i mirror

Code
04

Bidirectional

1,2,3 then 2,1

Shape
O 05

Complexity

O(n²) time

Analysis

❓ Frequently Asked Questions

For i = 5, the condition i < 4 is false, so the program prints 6 - 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 6 - 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.
Only one row prints — a single 1.

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.

Continue to Program 26

Move on to the descending number pattern with diagonal asterisk in the C number-pattern series.

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