Shape Rule
Left + right mirror
Left half grows 1..i; right half mirrors i..1 with spaces keeping alignment.

The mirrored number pattern prints 1 1, 12 21, 123 321, 1234 4321, 1234554321 — a natural step after the 0-centered mirror in Program 28. This tutorial covers fixed-width loops, space alignment, conditional printing, a live preview, worked PHP examples, edge cases, and complexity.
Left + right mirror
Left half grows 1..i; right half mirrors i..1 with spaces keeping alignment.
i = 1..rows
for ($i = 1; $i <= $rows; $i++) — one mirrored row per iteration.
1..rows
if ($j <= $i) prints digit; else prints a space.
rows..1
if ($k > $i) prints space; else prints k.
3–9 rows
Pick a row count and draw the spaced mirror pattern in the browser.
Complexity
Each row runs two loops of width rows — total work scales as n².
A mirrored number pattern prints an increasing left half (1..i) and a decreasing right half (i..1) on the same row. With rows = 5, spaces keep both halves aligned until the final row joins as 1234554321.
In PHP you use fixed-width inner loops: left loop prints digits or spaces with j <= i, right loop mirrors with k > i for spaces.
It combines conditional printing with space alignment — a step up from Program 28’s digit-only mirror.
Both inner loops always run rows times.
Print digit or space on the left half.
Print space or digit on the right half.
Follow Program 28; continue to Program 30 (right-aligned triangle) next.
In short: for each i, left loop prints j or space, right loop prints k or space, then echo PHP_EOL.
Given rows = 5, print a mirrored pattern: for each i, print digits or spaces in a fixed-width left loop, then digits or spaces in a fixed-width right loop.
// rows = 5 (conceptual shape)
// 1 1
// 12 21
// 123 321
// 1234 4321
// 1234554321 | Item | Type | Description |
|---|---|---|
rows | int | Pattern height — also the fixed width of both inner loops. |
i | int | Outer loop — current row; controls how many digits print on each side. |
j | int | Left loop — prints j when j <= i, else a space. |
k | int | Right loop — prints k when k <= i, else a space. |
for i from 1 to rows:
for j from 1 to rows:
if j <= i: print j
else: print space
for k from rows down to 1:
if k > i: print space
else: print k
print newline | Approach | Idea | Best for |
|---|---|---|
| if/else per loop | 1 1, 12 21, … | Learning and interviews |
| Ternary operator | echo ($j <= $i) ? $j : " "; | Compact console programs |
| User-input rows | (int) trim(fgets(STDIN)); | Flexible row count |
| Goal | Pattern |
|---|---|
| Walk rows | for ($i = 1; $i <= $rows; $i++) |
| Left half | if ($j <= $i) echo $j; else echo " "; |
| Right half | if ($k > $i) echo " "; else echo $k; |
| End the row | echo PHP_EOL; |
| Ternary form | echo ($j <= $i) ? $j : " "; |
| User input | (int) trim(fgets(STDIN)); |
Same spaced mirror — different ways to write the conditions and control rows.
i = 1..rowsOne mirrored row per iteration
j <= i ? j : " "Digit or space
k > i ? " " : kSpace or digit
2 x rowsBoth loops always width rows
Reach for this pattern when teaching fixed-width loops, space alignment, and conditional character output.
Natural follow-up after Program 28 — introduces space padding for symmetric alignment.
Outer/inner bound practice with an immediate visual check.
Combine loops with fgets(STDIN) for a flexible row count.
Compare Program 28 (0-centered mirror) and Program 30 (right-aligned triangle) next.
This is a console teaching pattern — not how you build modern app screens.
Key benefit: one small program that locks in nested loops, output sequencing, and O(n²) thinking.
Choose a row count between 3 and 9 and draw the spaced mirror pattern in the browser.
Three complete PHP programs — fixed rows, user input with ternary form, and a smaller trace demo. Click View Output to reveal sample console results.
Print five rows of the spaced mirror with if/else in both inner loops.
rows = 5Hard-coded row count — ideal for first demos and screenshots.
<?php
for ($i = 1; $i <= 5; $i++) {
for ($j = 1; $j <= 5; $j++) {
if ($j <= $i) {
echo $j;
} else {
echo " ";
}
}
for ($k = 5; $k >= 1; $k--) {
if ($k > $i) {
echo " ";
} else {
echo $k;
}
}
echo PHP_EOL;
} When i = 1, the left loop prints 1 and four spaces; the right prints four spaces then 1 — output 1 1. When i = 5, both halves fill all columns — output 1234554321 with no gap.
Read the row count with fgets(STDIN) instead of hard-coding 5.
Read rows with (int) trim(fgets(STDIN)); both inner loops use rows as the width.
<?php
echo "Enter rows: ";
$rows = (int) trim(fgets(STDIN));
if ($rows < 1) return;
for ($i = 1; $i <= $rows; $i++) {
for ($j = 1; $j <= $rows; $j++) {
echo ($j <= $i) ? $j : " ";
}
for ($k = $rows; $k >= 1; $k--) {
echo ($k > $i) ? " " : $k;
}
echo PHP_EOL;
} Same spaced-mirror core as Example 1; ternary operators replace if/else and rows replaces hard-coded 5. Non-numeric input leaves rows unset if you skip is_numeric() checks — always check it in safer labs.
Run with rows = 3 to trace every row on paper before scaling up.
rows = 3Same if/else logic with a smaller row count for quick tracing.
<?php
$rows = 3;
for ($i = 1; $i <= $rows; $i++) {
for ($j = 1; $j <= $rows; $j++) {
if ($j <= $i) {
echo $j;
} else {
echo " ";
}
}
for ($k = $rows; $k >= 1; $k--) {
if ($k > $i) {
echo " ";
} else {
echo $k;
}
}
echo PHP_EOL;
} Only rows changes from 5 to 3 — the if/else structure stays identical. Trace i = 1, 2, 3 on paper to see how spaces shrink each row.
Set $rows = 5; and use fgets(STDIN) when reading input. Set loop variables $i, $j, $k.
for ($i = 1; $i <= $rows; $i++) — ascending outer loop; one mirrored row per iteration.
for ($j = 1; $j <= $rows; $j++) — print j if j <= i, else a space.
for ($k = $rows; $k >= 1; $k--) — print space if k > i, else k.
echo PHP_EOL ends the row after both inner loops finish.
Spaces shrink each row until the final join — O(n²) time, O(1) extra memory.
rows = 5Trace each outer-loop value of i, what the left and right loops print, and the full row output.
i | Left (j) | Right (k) | Row output |
|---|---|---|---|
1 | 1, space, space, space, space | space, space, space, space, 1 | 1 1 |
2 | 1, 2, space, space, space | space, space, space, 2, 1 | 12 21 |
3 | 1, 2, 3, space, space | space, space, 3, 2, 1 | 123 321 |
4 | 1, 2, 3, 4, space | space, 4, 3, 2, 1 | 1234 4321 |
5 | 1, 2, 3, 4, 5 | 5, 4, 3, 2, 1 | 1234554321 |
Gap spaces = 2 * (rows - i) between the left and right digit groups — zero when i = rows.
Where this tiny pattern (and its loop structure) shows up beyond the homework prompt.
Clearest visual proof that outer and inner bounds interact.
Example: flip j <= i to j > i for digits and watch alignment break.
Foundation for inverted, pyramid, diamond, and hollow variants.
Example: continue to Program 30 for a right-aligned descending triangle.
Practice echo vs echo PHP_EOL without complex math.
Example: put echo PHP_EOL inside the inner loop by mistake.
Add spaces between digits once the two-loop structure works.
Example: use echo(j + " ") in both inner loops.
Triangular totals make O(n²) concrete for beginners.
Example: count printed characters for rows = 5 — each row prints 2 * rows characters.
Pair the pattern with fgets(STDIN) return checks and positive-row checks.
Example: reject max <= 0 and re-prompt.
Pro Tip: when an interviewer asks for patterns, explain the outer/inner roles first — then write the loops. The story matters as much as the code.
Why this pattern earns a permanent spot in beginner PHP courses.
Wrong bounds show up immediately as a broken staircase.
Only loops and console output — no arrays or math libraries.
Invert, center, hollow, or change the fill character with small edits.
Streaming output needs no storage beyond loop counters.
Pro Tip: trace i, j, and k on paper for rows = 3 before coding — watch how gap spaces shrink each row.
Small habits that keep number-pattern code clean.
Both inner loops must use rows as the bound — mismatched widths break alignment.
is_numeric()Call is_numeric(trim($line)) so bad input does not leave rows uninitialized.
Only call echo PHP_EOL after the inner loop finishes the row.
Mark the ascending half and mirror half for each row before coding.
Trace i = 1..3 on paper before coding the full rows = 5 demo.
Pro Tip: if the output is a vertical list of single digits per line, you almost certainly put echo PHP_EOL inside the inner loop.
Mistakes that commonly break spaced mirror patterns.
Each digit lands on its own line — you get a column, not a triangle.
→ Use echo $j, echo " ", or echo $k; echo PHP_EOL only after both inner loops.
Using k <= i for spaces on the right (instead of k > i) inverts the mirror half.
→ Left: print digit when j <= i. Right: print space when k > i.
Printing only digits without padding collapses the symmetric shape into a tight palindrome.
→ Use echo " " in the else branches to maintain fixed width.
Left loop to i but right loop to rows - 1 misaligns columns.
→ Both inner loops must run exactly rows iterations.
Letters or empty input leave rows uninitialized.
→ Call is_numeric(trim($line)) and re-prompt on failure.
Check these inputs before calling the solution done.
Output is 11 — both halves print one digit with no gap.
Outer loop never runs — print nothing or show a message.
rows < 0Treat as invalid; re-prompt instead of silent empty output.
Two rows: 1 1 and 1221.
Unchecked fgets(STDIN) input leaves rows unset — call is_numeric(trim($line)) first.
Each row prints 2 * rows characters — grows as rows² total work.
Try these variations to lock in the pattern.
" " with "." or "*"j <= i, space otherwise. Right loop: space when k > i, digit otherwise.echo stays on the line; echo PHP_EOL advances — mix them carefully.rows > 0 for interactive programs; rows = 1 prints 11.rows times — fixed width is what creates the alignment.Quick Takeaway: outer loop $i = 1..$rows, left j <= i ? j : " ", right k > i ? " " : k, then echo PHP_EOL.
| Program | Time | Extra space |
|---|---|---|
| Nested loops (Examples 1–3) | O(n²) | O(1) |
| Smaller demo (Example 3) | O(n²) | O(1) |
The mirrored number pattern is a compact lesson in fixed-width loops and space alignment: print digits or spaces on the left with j <= i, mirror on the right with k > i, and end each row with echo PHP_EOL. Master the fixed-rows version, then try user input and a smaller trace demo.
Practice the three examples above, then continue to Program 30 for the right-aligned descending number triangle.
Both inner loops must use rows as the width — validate rows when reading from the console.
for ($i = 1; $i <= $rows; $i++) in the outer loopif ($j <= $i) print digit, else print spaceif ($k > $i) print space, else print krowsis_numeric(trim($line)) before using rowsecho PHP_EOL inside either inner looprows = 1 edge casePrint the pattern the beginner-friendly way.
j<=i, k>i spaces
Definition2 x rows
CodeDigit or space
CodeSpace or digit
ShapeO(n²) time
AnalysisThis pattern prints an increasing left half (1..$i), then a mirrored right half ($i..1). Spaces in the fixed-width loops keep both halves aligned until the final row joins without a gap.
Move on to the right-aligned descending number triangle in the PHP number-pattern series.
12 people found this page helpful