Symmetric Dual-Column Number Diamond in PHP

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:
1
2 2
3 3
4 4
5 5
4 4
3 3
2 2
1Complete 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
// 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
First part: grow the row index
for ($i = 1; $i <= 5; $i++) prints the upper half including the widest row (5 5).
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.
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.
Line breaks
echo PHP_EOL; after each row in both phases.
Diamond complete
Total rows are 2n - 1 for peak n. Overall complexity is O(n²).
Variation — User Input (CLI) Version
This version reads peak row count n from stdin (run with php in a terminal):
<?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
ndown to1(duplicates the widest row) - Mismatched bounds between the two inner loops and
$n - Using HTML breaks instead of
PHP_EOLin CLI examples - Skipping input validation for
n
Key Takeaways
A diamond is often two copies of a half pattern with overlapping center handled carefully.
Here the mirror starts at i = n - 1 so the peak row prints once.
Each row still uses descending j and ascending k column scans.
Refactoring the row printer reduces bugs when you change spacing rules.
❓ Frequently Asked Questions
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).t from 0 to 2n-2 to row value min(t+1, 2n-1-t), then print that row.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.
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.
12 people found this page helpful
