Shape Rule
Shrinking rows
Row 1 prints five 1s, row 2 prints four 2s, row 5 prints a single 1.

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.
Shrinking rows
Row 1 prints five 1s, row 2 prints four 2s, row 5 prints a single 1.
i = 1..rows
for (i = 1; i <= rows; i++) walks each row top to bottom.
j = i..rows
for (j = i; j <= rows; j++) prints fewer digits as i grows.
6 - i mirror
i < 4 prints i; else prints 6 - i for rows 4 and 5.
3–9 rows
Pick a row count and draw the bidirectional triangle instantly in the browser.
Complexity
Total prints are triangular — scales as n² for n rows.
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.
It combines shrinking inner loops with conditional mapping — a step up from Program 24’s spacing logic.
j = i..rows — each row prints fewer digits.
i < 4 repeats 1, 2, 3.
6 - i produces 2 and 1 on last rows.
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.
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.
// rows = 5 (conceptual shape)
// 11111
// 2222
// 333
// 22
// 1 | Item | Type | Description |
|---|---|---|
rows | int | Number of rows — outer loop runs from 1 to rows. |
i | int | Outer loop — current row number (also the digit for early rows). |
j | int | Inner loop — j = i..rows controls shrinking row length. |
val | int | Digit to repeat — i or rows + 1 - i via if/else. |
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 | Idea | Best for |
|---|---|---|
| If/else mapping | 11111, 2222, … 1 | Learning and interviews |
| User-input rows | scanf("%d", &rows); | Flexible console programs |
| Ternary val | val = (i < rows - 1) ? i : (rows + 1 - i) | Compact generalized version |
| Goal | Pattern |
|---|---|
| Walk rows | for (i = 1; i <= rows; i++) |
| Shrink inner loop | for (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 row | printf("\n"); |
| User input | scanf("%d", &rows); |
Same bidirectional triangle — different ways to control rows and formatting.
i = 1..rowsOne row per outer iteration
j = i..rowsShrinking row length each row
6 - iMirrors digits on last rows
if/elseCompute val once per row, not per column
Reach for this pattern when teaching shrinking inner loops, conditional digit mapping, and bidirectional output.
Natural follow-up after Program 24 — introduces if/else mapping and shrinking rows.
Outer/inner bound practice with an immediate visual check.
Combine loops with scanf for a flexible row count.
Compare Program 24 (centered pyramid) and Program 26 (diagonal asterisk) next.
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.
Choose a row count between 3 and 9 and draw the bidirectional number triangle in the browser.
Three complete C programs — fixed rows, user input, and spaced output variant. Click View Output to reveal sample console results.
Print five rows of the bidirectional triangle with if/else mapping.
rows = 5Hard-coded row count — ideal for first demos and screenshots.
#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;
} 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.
Read the row count with scanf instead of hard-coding 5.
Read rows with scanf("%d", &rows); use a ternary to generalize the digit mapping.
#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;
} 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.
Add a space between repeated digits for easier reading.
Keep rows = 5 but print each digit followed by a space.
#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;
} Only the print statement changes — printf("%d ", val) instead of printf("%d", val). The shrinking loop and digit mapping stay the same.
#include <stdio.h> brings in printf / scanf. Set loop variables i, j and rows = 5.
for (i = 1; i <= rows; i++) — one row per iteration.
for (j = i; j <= rows; j++) — row length shrinks as i grows.
if (i < 4) prints i; else printf("%d", 6 - i) mirrors down.
printf("\n") ends the row after the inner loop.
Digits rise then mirror down — O(n²) time, O(1) extra memory.
rows = 5Trace each outer-loop value of i, the digit chosen, inner-loop count, and row output.
i | Digit (val) | Inner loop (j) | Prints | Row output |
|---|---|---|---|---|
1 | 1 (i < 4) | 1..5 (5 times) | 5 | 11111 |
2 | 2 | 2..5 (4 times) | 4 | 2222 |
3 | 3 | 3..5 (3 times) | 3 | 333 |
4 | 2 (6 - i) | 4..5 (2 times) | 2 | 22 |
5 | 1 (6 - i) | 5..5 (1 time) | 1 | 1 |
Prints per row = rows - i + 1 — total prints = n(n+1)/2 for n rows.
Where this tiny pattern (and its loop structure) shows up beyond the homework prompt.
Clearest visual proof that outer and inner bounds interact.
Example: change j = i to j = 1 and watch rows stop shrinking.
Foundation for inverted, pyramid, diamond, and hollow variants.
Example: use rows + 1 - i for a fully symmetric variant.
Practice printf vs row newline without complex math.
Example: put printf("\n") inside the inner loop by mistake.
Swap digits for letters or add spaces once the loop works.
Example: print val + " " for spaced repeated digits.
Triangular totals make O(n²) concrete for beginners.
Example: count printed numbers for rows = 5 → 5 + 4 + 3 + 2 + 1 = 15.
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.
Why this pattern earns a permanent spot in beginner C courses.
Wrong bounds show up immediately as a broken staircase.
Only loops and console output — no arrays or math libraries.
Invert, center, hollow, or change the fill character with small edits.
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.
Small habits that keep number-pattern code clean.
Do not reset val inside the inner loop — compute it once per row.
scanfCheck the return value so bad input does not leave rows uninitialized.
Only call printf("\n") after the inner loop finishes the row.
Write each i, digit chosen, and print count before coding.
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.
Mistakes that commonly break bidirectional number triangle patterns.
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.
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).
Using j = 1 to rows prints full-width rows — no shrinking.
→ Use for (j = i; j <= rows; j++) so each row is shorter.
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).
Letters or empty input leave rows uninitialized.
→ Check scanf return value and re-prompt on failure.
Check these inputs before calling the solution done.
Output is just 1 — one digit, one row.
Outer loop never runs — print nothing or show a message.
rows < 0Treat as invalid; re-prompt instead of silent empty output.
Two rows: 11 and 1.
Unchecked scanf leaves rows unset — check the return value.
Output grows as n² characters — fine for labs, noisy for huge n.
Try these variations to lock in the pattern.
* on diagonalPrintTriangle(int rows)Main with user inputrows + 1 - i for all rows, not just last twoj = i..rows — row length = rows - i + 1 digits per row.printf("%d", val) repeats the digit; printf("\n") advances — mix them carefully.rows > 0 for interactive programs; rows = 1 prints a single 1.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.
| Program | Time | Extra space |
|---|---|---|
| Nested loops (Examples 1–2) | O(n²) | O(1) |
| Spaced output (Example 3) | O(n²) | O(1) |
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.
for (i = 1; i <= rows; i++) in the outer loopfor (j = i; j <= rows; j++)val once per row before the inner loopscanf return value before using rowsprintf("\n") inside the inner loopj = 1 in the inner loop — rows won’t shrink6 - i in generalized code — use rows + 1 - irows = 1 edge casePrint the pattern the beginner-friendly way.
Shrink + repeat
DefinitionShrinking rows
Code6 - i mirror
Code1,2,3 then 2,1
ShapeO(n²) time
AnalysisThis 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.
Move on to the descending number pattern with diagonal asterisk in the C number-pattern series.
12 people found this page helpful