Symmetric Dual-Column Number Diamond in PHP

Beginner
⏱️ 7 min read
📚 Updated: Aug 2025
🎯 2 Code Examples
Two-Phase Nested Loops

What You’ll Learn

How to build a number diamond by running the same “dual-column row” logic twice: first while the row index grows, then while it shrinks.

This extends Program 57 with a mirrored second half so the widest row appears only once at the center.

⭐ Pattern Output

For peak row 5, the pattern looks like this:

Output
    1
   2 2
  3   3
 4     4
5       5
 4     4
  3   3
   2 2
    1
1

Complete PHP Program

First phase: i = 1..5. Second phase: i = 4..1. Each phase prints one row using the same inner loops as Program 57.

PHP
<?php
// First part
for ($i = 1; $i <= 5; $i++) {
    for ($j = 5; $j >= 1; $j--) {
        if ($i == $j) {
            echo $j;
        } else {
            echo " ";
        }
    }
    for ($k = 2; $k <= 5; $k++) {
        if ($i == $k) {
            echo $k;
        } else {
            echo " ";
        }
    }
    echo PHP_EOL;
}
// Second part
for ($i = 4; $i >= 1; $i--) {
    for ($j = 5; $j >= 1; $j--) {
        if ($i == $j) {
            echo $j;
        } else {
            echo " ";
        }
    }
    for ($k = 2; $k <= 5; $k++) {
        if ($i == $k) {
            echo $k;
        } else {
            echo " ";
        }
    }
    echo PHP_EOL;
}

🧠 How It Works

1

First part: grow the row index

for ($i = 1; $i <= 5; $i++) prints the upper half including the widest row (5 5).

Ascending phase
2

Per-row: two column scans

For each $i, loop $j from 5 to 1, then $k from 2 to 5; print the index when it equals $i, else a space.

Same as Program 57
3

Second part: shrink the row index

for ($i = 4; $i >= 1; $i--) repeats the same inner loops so rows mirror below the peak without repeating i = 5.

Descending phase
4

Line breaks

echo PHP_EOL; after each row in both phases.

Formatting
=

Diamond complete

Total rows are 2n - 1 for peak n. Overall complexity is O(n²).

2

Variation — User Input (CLI) Version

This version reads peak row count n from stdin (run with php in a terminal):

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

if ($n < 1) {
    echo "n must be at least 1" . PHP_EOL;
    exit;
}

for ($i = 1; $i <= $n; $i++) {
    for ($j = $n; $j >= 1; $j--) {
        if ($i == $j) {
            echo $j;
        } else {
            echo " ";
        }
    }
    for ($k = 2; $k <= $n; $k++) {
        if ($i == $k) {
            echo $k;
        } else {
            echo " ";
        }
    }
    echo PHP_EOL;
}

for ($i = $n - 1; $i >= 1; $i--) {
    for ($j = $n; $j >= 1; $j--) {
        if ($i == $j) {
            echo $j;
        } else {
            echo " ";
        }
    }
    for ($k = 2; $k <= $n; $k++) {
        if ($i == $k) {
            echo $k;
        } else {
            echo " ";
        }
    }
    echo PHP_EOL;
}

💡 Tips for Enhancement

Try These

  • Extract a printRow($i, $n) function to remove duplicated inner loops
  • Swap spaces for dots or dashes for a hollow-bridge look
  • Print row labels in the margin for debugging wide diamonds
  • Try even peak sizes and observe spacing (still valid with this grid model)
  • Combine with Program 56-style padding for stronger centering

Avoid

  • Running the second phase from n down to 1 (duplicates the widest row)
  • Mismatched bounds between the two inner loops and $n
  • Using HTML breaks instead of PHP_EOL in CLI examples
  • Skipping input validation for n

Key Takeaways

1

A diamond is often two copies of a half pattern with overlapping center handled carefully.

2

Here the mirror starts at i = n - 1 so the peak row prints once.

3

Each row still uses descending j and ascending k column scans.

4

Refactoring the row printer reduces bugs when you change spacing rules.

❓ Frequently Asked Questions

Row 5 is already printed at the end of the first part. Starting at 4 mirrors the shape without duplicating that line.
2n - 1 lines for peak row index n (for example, 9 lines when n = 5).
Yes. For example map a single index t from 0 to 2n-2 to row value min(t+1, 2n-1-t), then print that row.
O(n²) for peak n, because there are O(n) rows and each row scans O(n) positions.

Explore More PHP Number Patterns!

Combine ascending and descending phases to build diamonds, hourglasses, and mirrored layouts.

All Number Patterns →
Did you know?

Splitting a diamond into “upper” and “lower” phases is easier to read than one clever index formula, and both compile to similar performance for small n.

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