A bidirectional number triangle repeats one digit per row while the row length shrinks. Digits rise on early rows, then mirror down on the last rows.
Remember
Rule: for i from 1 to rows,
repeat val (rows - i + 1) times
val = i if i < rows - 1, else rows + 1 - i
11111
2222
333
22
1 ← rows = 5
Natural step after Program 24 (centered pyramid) — here the focus is shrinking rows plus an if/else digit map.
Approach
How to Solve It
Shrink with j = i..rows; pick the digit with a simple threshold.
Method
Idea
Best for
If/else map
Print i early; print rows + 1 - i on the last rows
Learning, interviews, exams
Spaced digits
Same loops; print val + " "
When you want gaps between repeats
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
Goal
Pattern
Walk rows
for (int i = 1; i <= rows; i++)
Shrink length
for (int j = i; j <= rows; j++)
Fixed map (n = 5)
if (i < 4) print(i); else print(6 - i);
General map
val = (i < rows - 1) ? i : (rows + 1 - i);
End the row
System.out.println();
Spaced digits
System.out.print(val + " ");
Printing Numbers vs Starting a New Line
API
Effect
Use for
System.out.print
Stays on the same line
Each repeated digit val
System.out.println
Ends the current line
After the inner loop
Print digits without a newline, then end the row once.
Try it
Live Preview
Change the row count and the bidirectional triangle updates instantly.
Whole numbers from 3 to 9 (enough rows for the rise-then-mirror effect). Tap a chip or type a value.
Live resultrows = 5 · 15 digits
11111
2222
333
22
1
Trace
Worked Walkthrough — rows = 5
Trace each row’s digit, print count, and printed line.
i
val
Prints
Printed row
1
1 (i < 4)
5
11111
2
2
4
2222
3
3
3
333
4
2 (6 - i)
2
22
5
1 (6 - i)
1
1
Total digits: 5 + 4 + 3 + 2 + 1 = 15 = n(n + 1) / 2 — that is why time is O(n²).
Code
Java Programs
Three complete programs: fixed rows = 5, Scanner input with a general ternary, and spaced digits. Use View Output to reveal sample results.
Example 1 — Fixed rows = 5
Hard-coded height — shrink with j = i..5; map digits with i < 4.
Java
public class BidirectionalTriangle {
public static void main(String[] args) {
for (int i = 1; i <= 5; i++) {
for (int j = i; j <= 5; j++) {
if (i < 4)
System.out.print(i);
else
System.out.print(6 - i);
}
System.out.println();
}
}
}
Output
11111
2222
333
22
1
How It Works
1. Outer loop walks rows.i runs from 1 to 5.
2. Inner loop shrinks.j runs from i to 5 — row length is 6 - i.
3. Digit map. If i < 4, repeat i; else repeat 6 - i (so row 4 → 2, row 5 → 1).
When i = 3, print three 3s. When i = 4, print two 2s.
Example 2 — Rows Input
Read rows at runtime. Use a ternary so the digit map works for any height.
Java
import java.util.Scanner;
public class BidirectionalTriangleInput {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("Enter rows: ");
int rows = sc.nextInt();
for (int i = 1; i <= rows; i++) {
int val = (i < rows - 1) ? i : (rows + 1 - i);
for (int j = i; j <= rows; j++)
System.out.print(val);
System.out.println();
}
sc.close();
}
}
Output (when user enters 5)
Enter rows: 5
11111
2222
333
22
1
How It Works
1. Prompt and read. Ask for a height, then store it with sc.nextInt().
2. General digit map.(i < rows - 1) ? i : (rows + 1 - i) replaces the hard-coded 4 and 6.
3. Safer input tip. Prefer:
Safer input
if (!sc.hasNextInt()) {
System.out.println("Enter a positive whole number.");
return;
}
int rows = sc.nextInt();
if (rows < 1) {
System.out.println("Enter a positive whole number.");
return;
}
Example 3 — Spaced Digits
Keep rows = 5 but print each digit followed by a space.
Java
public class BidirectionalTriangleSpaced {
public static void main(String[] args) {
int rows = 5;
for (int i = 1; i <= rows; i++) {
int val = (i < rows - 1) ? i : (rows + 1 - i);
for (int j = i; j <= rows; j++)
System.out.print(val + " ");
System.out.println();
}
}
}
Output
1 1 1 1 1
2 2 2 2
3 3 3
2 2
1
How It Works
1. Same map and shrink. Digit choice and j = i..rows match Examples 1 and 2.
2. Only the print changes.print(val + " ") adds a space after each digit.
3. Same shape. Row lengths and bidirectional values are unchanged — only spacing differs.
Edge Cases & Pitfalls
Check these before calling the solution done.
j = 1
No shrink
Starting the inner loop at 1 prints full-width rows. Use j = i so each row is shorter.
Wrong threshold
Missed mirror
Using i < rows instead of i < rows - 1 skips the mirror on the last rows. Prefer the ternary from Example 2.
println inside
Column of digits
If println is inside the inner loop, each digit lands on its own line. Use print for digits; println only after the inner loop.
rows = 1
Single 1
Output is just 1 — a good sanity check.
rows = 2
Smallest triangle
Two rows: 11 and 1 (both use the mirror branch when rows - 1 = 1).
Bad input
Use hasNextInt
nextInt() throws on letters — prefer hasNextInt() and require a positive whole number.
Analysis
Time and Space Complexity
Program
Time
Extra space
Bidirectional triangle (Examples 1–3)
O(n²)
O(1)
Total digit prints: n + (n − 1) + … + 1 = n(n + 1) / 2 — still quadratic in n.
Remember
Key Takeaways
Rule: shrink with j = i..rows; digit is i early, then rows + 1 - i.
Threshold: switch at i < rows - 1 — that creates the bidirectional effect.
Break the row: call println only after the inner loop.
Complexity:O(n²) time; O(1) extra space.
One line: shrink the row, pick val with a threshold, repeat val, then println().
Frequently Asked Questions
For rows = 5 and 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 rows + 1 − i mapping.
System.out.print(val) repeats the digit on the same line. System.out.println() 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).
Use sc.hasNextInt() before sc.nextInt(), require rows ≥ 1, and reject non-numeric input — see Example 2 notes.
🤔
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.