A bidirectional number triangle prints a shrinking row of the same digit, where the digit rises on early rows then mirrors back down on the last rows.
Remember
Rule: shrink j = i..n; digit = i or n+1-i
11111
2222
333
22
1 ← 5 rows
In C# the outer loop picks the row, the inner loop prints one digit repeatedly from i to rows, and an if/else (or ternary) chooses i vs rows + 1 - i. Then Console.WriteLine() ends each row.
Approach
How to Solve It
One nested-loop idea with two useful variants — packed digits and spaced digits.
Method
Idea
Best for
Shrink + map digit
Inner j = i..rows; digit is i then rows + 1 - i
Learning, interviews, exams
Spaced digits
Same logic; print val + " "
Practice variants
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
Goal
Pattern
Walk each row
for (i = 1; i <= rows; i++)
Shrink the length
for (j = i; j <= rows; j++)
Pick the digit
val = (i < rows - 1) ? i : (rows + 1 - i);
Repeat the digit
Console.Write(val);
End the row
Console.WriteLine();
Write vs WriteLine
API
Effect
Use for
Console.Write
Stays on the same line
Each repeated digit val
Console.WriteLine
Ends the current line
After the inner loop
Try it
Live Preview
Change the row count and the bidirectional 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 result5 rows · 15 digits
11111
2222
333
22
1
Trace
Worked Walkthrough — rows = 5
Trace each outer-loop value of i, the mapped digit, and how many times it prints.
i
Digit val
Times (j = i..5)
Printed row
1
1 (i < 4)
5
11111
2
2
4
2222
3
3
3
333
4
2 (6 - i)
2
22
5
1
1
1
Total digits are 5+4+3+2+1 = 15 — the triangular number n(n+1)/2.
Code
C# Programs
Three complete programs: fixed height, generalized row count, and spaced digits. Use View Output for sample results.
Example 1 — Fixed rows = 5
Shrink each row; map the digit with if (i < 4) else 6 - i.
C#
using System;
namespace MyApp
{
class Program
{
static void Main(string[] args)
{
int i, j;
for (i = 1; i <= 5; i++)
{
for (j = i; j <= 5; j++)
{
if (i < 4)
Console.Write(i);
else
Console.Write(6 - i);
}
Console.WriteLine();
}
}
}
}
Output
11111
2222
333
22
1
How It Works
1. Shrink the length.for (j = i; j <= 5; j++) prints 5, 4, 3, 2, then 1 digits.
2. Map the digit. Early rows use i (1, 2, 3); later rows use 6 - i (2, 1).
3. Newline.WriteLine() after the inner loop starts the next shorter row.
Example 2 — User Input
Generalize the mapping with rows. Prefer int.TryParse so bad input does not throw.
C#
using System;
namespace MyApp
{
class Program
{
static void Main(string[] args)
{
int rows;
int i, j, val;
Console.Write("Enter rows: ");
if (!int.TryParse(Console.ReadLine(), out rows) || rows < 1)
{
Console.WriteLine("Please enter a positive whole number.");
return;
}
for (i = 1; i <= rows; i++)
{
val = (i < rows - 1) ? i : (rows + 1 - i);
for (j = i; j <= rows; j++)
{
Console.Write(val);
}
Console.WriteLine();
}
}
}
}
2. Compute val once. Set the digit before the inner loop, then just Write(val) repeatedly.
Example 3 — Spaced Digits
Same mapping and shrink — 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, val;
for (i = 1; i <= rows; i++)
{
val = (i < rows - 1) ? i : (rows + 1 - i);
for (j = i; j <= rows; j++)
{
Console.Write(val + " ");
}
Console.WriteLine();
}
}
}
}
Output
1 1 1 1 1
2 2 2 2
3 3 3
2 2
1
How It Works
1. Same digit map.val still rises then mirrors down.
For general rows, use i < rows - 1 and rows + 1 - i (Example 2).
wrong start
j = 1 instead of j = i
That prints a full-width rectangle. Keep for (j = i; j <= rows; j++).
WriteLine early
WriteLine(val) inside the inner loop
That puts each digit on its own line. Use Write(val); call WriteLine() only after the row finishes.
rows = 1
Single 1
Output is just 1 — a good sanity check.
rows = 2
Both rows mirror
With rows - 1 = 1, both rows use the mirror formula — output is 11 then 1.
Bad input
Convert.ToInt32 throws
Prefer int.TryParse so non-numeric input does not crash the program.
Analysis
Time and Space Complexity
Program
Time
Extra 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.
Remember
Key Takeaways
Rule: shrink with j = i..rows; digit is i then rows + 1 - i.
Map once: compute val before the inner loop, then just repeat it.
Write vs WriteLine: digits stay on the line; WriteLine advances after each row.
Next step: Program 26 mixes descending numbers with a diagonal asterisk.
One line: for each row, pick a rising-then-mirroring digit and print it rows - i + 1 times.
Frequently Asked Questions
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.
Console.Write repeats the digit on the same line. Console.WriteLine 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 hard-coded 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).
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 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.