PHP Palindrome Number Triangle Pattern

Definition
What Is This Pattern?
A palindrome number triangle prints ascending digits 1..$i, then mirrors with $i-1..1 — each row reads the same forwards and backwards.
Rule: for i from 1 to rows
print j from 1 to i
print k from i-1 down to 1
1
121
12321
1234321
123454321 ← rows = 5
Follows the diagonal asterisk pattern in Program 26; next is the 0-centered descending mirror in Program 28.
Approach
How to Solve It
Outer loop grows $i. First inner loop prints 1..$i; second prints $i-1..1 so the peak digit appears once.
| Method | Idea | Best for |
|---|
| Two inner loops | Ascend 1..$i, then descend $i-1..1 | Learning, interviews, exams |
| Spaced digits | Same loops with echo $j . " " | Easier reading for larger peaks |
Pseudocode
for i from 1 to rows:
for j from 1 to i:
print j
for k from i - 1 down to 1:
print k
print newline
Cheat sheet
| Goal | Pattern |
|---|
| Grow each row | for ($i = 1; $i <= $rows; $i++) |
| Left ascending | for ($j = 1; $j <= $i; $j++) echo $j; |
| Right mirror | for ($k = $i - 1; $k >= 1; $k--) echo $k; |
| Avoid double peak | Start the mirror at $i - 1, not $i |
| End of row | echo PHP_EOL; |
Printing Numbers vs Starting a New Line
| API | Effect | Use for |
|---|
echo $j / $k | Stays on the same line | Each digit on the row |
echo PHP_EOL | Ends the current line | After both inner loops finish |
Print digits without a newline, then end the row once.
Try it
Live Preview
Change the row count and the palindrome triangle updates instantly — capped at 9 for readable demos.
Trace
Worked Walkthrough — $rows = 5
Trace how ascending then descending halves build each palindrome row.
$i | Ascending | Mirror | Prints |
|---|
1 | 1 | (none) | 1 |
2 | 12 | 1 | 121 |
3 | 123 | 21 | 12321 |
4 | 1234 | 321 | 1234321 |
5 | 12345 | 4321 | 123454321 |
Row $i prints 2i - 1 digits. Total = 1 + 3 + … + (2n-1) = n² → O(n²).
Code
PHP Programs
Three complete programs: fixed $rows = 5, CLI input, and a compact $rows = 3 demo. Use View Output to reveal sample results.
Example 1 — Fixed $rows = 5
Hard-coded height — ascend 1..$i, then mirror $i-1..1.
<?php
$rows = 5;
for ($i = 1; $i <= $rows; $i++) {
for ($j = 1; $j <= $i; $j++) {
echo $j;
}
for ($k = $i - 1; $k >= 1; $k--) {
echo $k;
}
echo PHP_EOL;
}
?>
1
121
12321
1234321
123454321
How It Works
1. Outer grows the peak. $i is both the row index and the middle digit.
2. Ascend then mirror. Print 1..$i, then $i-1..1 so the peak is not repeated.
3. Newline once. Call echo PHP_EOL only after both inner loops finish.
Example 2 — User Input Rows
Read $rows from the CLI, validate, then use the same two-loop core.
<?php
echo "Enter rows: ";
$input = trim(fgets(STDIN));
if (!is_numeric($input) || (int) $input <= 0) {
echo "Please enter a positive integer." . PHP_EOL;
exit(1);
}
$rows = (int) $input;
for ($i = 1; $i <= $rows; $i++) {
for ($j = 1; $j <= $i; $j++) {
echo $j;
}
for ($k = $i - 1; $k >= 1; $k--) {
echo $k;
}
echo PHP_EOL;
}
?>
How It Works
1. Prompt and validate. Reject non-numeric and non-positive values before printing.
2. Same core. Ascend + mirror matches Example 1 — only $rows comes from the user.
3. Safer input tip. Cap demos for readable output:
if (!is_numeric($input) || (int) $input < 1 || (int) $input > 9) {
echo "Enter a whole number from 1 to 9." . PHP_EOL;
exit(1);
}
Example 3 — Compact $rows = 3
Same structure with only three rows — easy to confirm the mirror start at $i - 1.
<?php
$rows = 3;
for ($i = 1; $i <= $rows; $i++) {
for ($j = 1; $j <= $i; $j++) {
echo $j;
}
for ($k = $i - 1; $k >= 1; $k--) {
echo $k;
}
echo PHP_EOL;
}
?>
How It Works
1. Three rows. $i = 1 → 1; $i = 2 → 121; $i = 3 → 12321.
2. Trace on paper. If the mirror starts at $i instead of $i - 1, you get a doubled peak (123321).
3. Scale up next. Once the small demo is clear, use Examples 1–2 for five rows or user input.
Edge Cases & Pitfalls
Check these before calling the solution done.
k = iDoubled peak
Starting the mirror at $i prints the middle digit twice (123321). Use $k = $i - 1.
no mirrorMissing descending loop
Without the second loop you get 1, 12, 123 — not palindromes. Keep both inners.
PHP_EOL insideBroken rows
If echo PHP_EOL sits inside either inner loop, the palindrome splits across lines. Call it only after both finish.
rows = 1Single digit
Output is just 1 — the mirror loop never runs. A good sanity check for input validation.
rows > 9Multi-digit glue
Digits run together (…91011…). Cap demos or add spaces with echo $j . " ".
fgetsCheck is_numeric
Bare (int) casts turn non-numeric strings into 0 — prefer is_numeric before casting.
Analysis
Time and Space Complexity
| Program | Time | Extra space |
|---|
| Fixed / input (Examples 1–2) | O(n²) | O(1) |
| Compact rows = 3 (Example 3) | O(n²) | O(1) |
Row $i prints 2i - 1 digits. Total = 1 + 3 + … + (2n-1) = n² → O(n²) time. Only a few loop variables are needed.
Remember
Key Takeaways
Two halves: print 1..$i, then mirror with $i-1..1.
Start at i-1: the descending loop must not repeat the peak digit.
Break the row: digits in both inners; echo PHP_EOL after both finish.
Complexity: O(n²) time from n² digits; O(1) extra space.
One line: for each row $i, print 1..$i then $i-1..1, then echo PHP_EOL.
Frequently Asked Questions
A palindrome number triangle: for rows=5 you get 1 / 121 / 12321 / 1234321 / 123454321 — each row reads the same forwards and backwards.
Starting from $i - 1 avoids repeating the middle number. For $i = 3, printing 123 then 21 makes 12321.
The ascending loop prints 1..$i and the descending loop prints $i-1..1 — together they read the same forwards and backwards.
echo $j prints digits on the same line. echo PHP_EOL ends the row after both inner loops finish.
One loop handles the ascending half and the other handles the mirror half — clearer than a single complex loop.
Use echo $j . " " and echo $k . " " in the loops instead of echo $j.
Use trim(fgets(STDIN)) and check is_numeric($input) before casting to int — see Example 2.
O(n²) for n rows because row i prints 2i-1 digits and the total is 1+3+5+…+(2n-1) = n².
🤔
Did you know?
This palindrome triangle prints 1..$i and then $i-1..1 on each row. The second loop mirrors the first, producing outputs like 12321 and 123454321.
Next: 0-Centered Descending Mirror
Continue with a mirror pattern that places 0 in the center.
Program 28 tutorial →About the author
Developer, cloud engineer, and technical writer
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