PHP Number Triangle Pattern (Bidirectional)

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

What Is This Pattern?

A bidirectional number triangle prints a shrinking row of the same digit each time — digits rise on early rows (1, 2, 3), then mirror down (2, 1).

Remember
Rule: for i = 1..rows
      val = i if i < rows-1, else rows+1-i
      print val repeated (rows - i + 1) times

11111
2222
333
22
1           ← rows = 5

After Program 24’s centered continuous pyramid, this pattern focuses on a shrinking inner bound plus a simple digit map.

How to Solve It

Walk $i from 1 to $rows; pick the row digit, then repeat it from $j = $i to $rows.

MethodIdeaBest for
Map + shrinkDigit from if/else or ternary; inner $j = $i..$rowsLearning, interviews
CLI inputSame loops; read $rows with fgets(STDIN)Interactive practice
Spaced digitsSame bounds; echo $val . " "Readable console output

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
Set rows$rows = 5;
Outer loopfor ($i = 1; $i <= $rows; $i++)
Digit map$val = ($i < $rows - 1) ? $i : ($rows + 1 - $i);
Inner loopfor ($j = $i; $j <= $rows; $j++)
Print digitecho $val;
End rowecho PHP_EOL;
Chars per row$rows - $i + 1

Printing Numbers vs Starting a New Line

APIEffectUse for
echo $valStays on the same lineEach digit
echo PHP_EOLEnds the current lineAfter the inner loop

Print all digits without a newline, then end the row once with echo PHP_EOL. Putting PHP_EOL inside the inner loop prints one digit per line.

Live Preview

Change the row count and the bidirectional triangle updates instantly.

Whole numbers from 3 to 9 so the rise-and-fall shape is clear. Tap a chip or type a value.

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

Worked Walkthrough — $rows = 5

Trace each outer $i, the mapped digit, how many times it repeats, and the printed row.

$i$valRepeatsPrinted row
11511111
2242222
333333
42 (6 - 4)222
51 (6 - 5)11

When $i < 4, use $i; otherwise use 6 - $i. Total digits = 15 = 5×6/2.

PHP Programs

Three complete programs: fixed $rows = 5, CLI input, and spaced digits. Use View Output for sample results.

Example 1 — Fixed $rows = 5

Hard-coded height — if/else digit map and a shrinking inner loop.

PHP
<?php
for ($i = 1; $i <= 5; $i++) {
    for ($j = $i; $j <= 5; $j++) {
        if ($i < 4) {
            echo $i;
        } else {
            echo 6 - $i;
        }
    }
    echo PHP_EOL;
}
?>

How It Works

1. Outer loop. $i runs from 1 to 5 — one shrinking row each time.

2. Digit map. If $i < 4, print $i; else print 6 - $i (so rows 4 and 5 become 22 and 1).

3. Inner loop. $j runs from $i to 5, then echo PHP_EOL ends the row.

Example 2 — CLI Input

Read $rows from STDIN and use a ternary that works for any height.

PHP
<?php
echo "Enter rows: ";
$rows = (int) trim(fgets(STDIN));

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

    for ($j = $i; $j <= $rows; $j++) {
        echo $val;
    }

    echo PHP_EOL;
}
?>

How It Works

1. Read rows. Ask for a count, then trim(fgets(STDIN)) and cast to int.

2. General map. ($i < $rows - 1) ? $i : ($rows + 1 - $i) replaces the hard-coded 4 and 6.

3. Safer input tip. Bare (int) casts turn letters into 0. Prefer:

Safer input
echo "Enter rows: ";
$input = trim(fgets(STDIN));
if (!is_numeric($input) || (int) $input < 1) {
    echo "Enter a positive whole number." . PHP_EOL;
    exit(1);
}
$rows = (int) $input;

Example 3 — Spaced Digits

Same loops; append a space after each digit for easier reading.

PHP
<?php
$rows = 5;

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

    for ($j = $i; $j <= $rows; $j++) {
        echo $val . " ";
    }

    echo PHP_EOL;
}
?>

How It Works

1. Same structure. Outer loop, digit map, and inner bounds match Example 2.

2. Only the print changes. echo $val . " " adds a trailing space after each digit.

3. Shape unchanged. Still rises then mirrors down while shrinking each row.

Edge Cases & Pitfalls

Check these before calling the solution done.

hard-coded 4 / 6

Breaks for other heights

$i < 4 and 6 - $i only work for $rows = 5. Use the ternary with $rows for any size.

fixed inner

Full rectangle

If the inner loop always runs 1..$rows, every row has the same length. Start at $j = $i.

PHP_EOL inside

Vertical digits

If echo PHP_EOL is inside the inner loop, each digit lands on its own line.

map inside

Repeated if

Set $val once before the inner loop, then just echo $val — do not recompute the map on every $j.

rows = 1

Single digit

Output is just 1 — a good sanity check.

fgets

Check is_numeric

Bare (int) casts turn non-numeric strings into 0 — prefer is_numeric before casting.

Time and Space Complexity

ProgramTimeExtra space
Examples 1–3O(n²)O(1)

Digits per pattern = n + (n-1) + … + 1 = n(n+1)/2 → O(n²).

Key Takeaways

  • Rule: shrink with $j = $i..$rows; map the digit with rise-then-fall.
  • General map: ($i < $rows - 1) ? $i : ($rows + 1 - $i).
  • echo vs PHP_EOL: digits stay on the line; echo PHP_EOL advances after each row.
  • Complexity: total digits = n(n+1)/2 → O(n²).

One line: shrink each row while the digit rises then mirrors back down.

Frequently Asked Questions

For $i = 5 and $rows = 5, the mapping uses $rows + 1 - $i = 6 - 5 = 1, so the last row prints a single 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.
echo $val repeats the digit on the same line. echo PHP_EOL ends the row after the inner loop finishes.
A single inner loop with a digit mapping keeps the shrinking row logic in one place.
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 trim(fgets(STDIN)) and check is_numeric($input) before casting to int.
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.

Next: Diagonal Asterisk Pattern

Continue with the next pattern in the PHP 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