Shape Rule
Palindrome rows
Each row reads the same forwards and backwards — 12321 is a palindrome.

The palindrome number triangle prints 1, 121, 12321, 1234321, 123454321 — a natural step after the diagonal asterisk pattern in Program 26. This tutorial covers ascending and descending inner loops, mirroring, a live preview, algorithm steps, worked PHP examples, edge cases, and complexity.
Palindrome rows
Each row reads the same forwards and backwards — 12321 is a palindrome.
i = 1..rows
for ($i = 1; $i <= $rows; $i++) grows the palindrome length each row.
1..i
for ($j = 1; $j <= $i; $j++) prints the left half of each row.
i-1..1
for ($k = $i - 1; $k >= 1; $k--) mirrors without repeating the peak.
3–9 rows
Pick a row count and draw the palindrome triangle instantly in the browser.
Complexity
Total prints grow as n² — row i prints 2i - 1 digits.
A palindrome number triangle prints an ascending sequence then mirrors it back down on the same row. With rows = 5, the output is 1, 121, 12321, 1234321, 123454321.
In PHP you use an outer loop for rows, an ascending inner loop j = 1..i, then a descending inner loop k = i-1..1.
It combines two inner loops for symmetry — a step up from Program 26’s single conditional swap.
First inner loop prints ascending digits.
Second loop mirrors without repeating the peak.
Each row reads the same forwards and backwards.
Follow Program 26; continue to Program 28 (0-centered mirror) next.
In short: for each i, print 1..i then i-1..1, then echo PHP_EOL.
Given a positive integer rows (e.g. 5), print a palindrome triangle: for each i, print 1..i then i-1..1 on the same line.
// rows = 5 (conceptual shape)
// 1
// 121
// 12321
// 1234321
// 123454321 | Item | Type | Description |
|---|---|---|
rows | int | Number of rows — outer loop runs from 1 to rows. |
i | int | Outer loop — current row; also the peak digit of the palindrome. |
j | int | Ascending loop — prints 1..i (left half). |
k | int | Descending loop — prints i-1..1 (right half). |
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 | Approach | Idea | Best for |
|---|---|---|
| Two inner loops | 1, 121, 12321, … | Learning and interviews |
| User-input rows | (int) trim(fgets(STDIN)); | Flexible console programs |
| Spaced output | echo $j . " " | Easier reading for wide rows |
| Goal | Pattern |
|---|---|
| Walk rows | for ($i = 1; $i <= $rows; $i++) |
| Ascending half | for ($j = 1; $j <= $i; $j++) echo $j; |
| Descending half | for ($k = $i - 1; $k >= 1; $k--) echo $k; |
| End the row | echo PHP_EOL; |
| Spaced digits | echo $j . " "; in both loops |
| User input | (int) trim(fgets(STDIN)); |
Same palindrome triangle — different ways to control rows and formatting.
i = 1..rowsGrows palindrome length each row
j = 1..iAscending digits
k = i-1..1Mirror without repeating peak
k = i-1Start mirror at i-1, not i
Reach for this pattern when teaching symmetry with two inner loops and palindrome row construction.
Natural follow-up after Program 26 — introduces two inner loops for mirroring.
Outer/inner bound practice with an immediate visual check.
Combine loops with fgets(STDIN) for a flexible row count.
Compare Program 26 (diagonal asterisk) and Program 28 (0-centered mirror) 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 palindrome number triangle in the browser.
Three complete PHP programs — fixed rows, user input, and spaced output variant. Click View Output to reveal sample console results.
Print five rows of the palindrome triangle with ascending and descending inner loops.
rows = 5Hard-coded row count — ideal for first demos and screenshots.
<?php
for ($i = 1; $i <= 5; $i++) {
for ($j = 1; $j <= $i; $j++) {
echo $j;
}
for ($k = $i - 1; $k >= 1; $k--) {
echo $k;
}
echo PHP_EOL;
} When i = 1, only the ascending loop runs — output 1. When i = 3, print 123 then mirror 21 — output 12321. The second loop starts at i - 1 so the peak digit is not repeated.
Read the row count with fgets(STDIN) instead of hard-coding 5.
Read rows with (int) trim(fgets(STDIN)); both inner loops use i as the bound.
<?php
echo "Enter rows: ";
$rows = (int) trim(fgets(STDIN));
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;
} Same two-loop core as Example 1; only the outer bound changes from 5 to rows. The palindrome length grows with each row. Non-numeric input leaves rows unset if you skip is_numeric() checks — always check it in safer labs.
Add a space between digits for easier reading on wide rows.
Keep rows = 5 but print each digit followed by a space in both loops.
<?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;
} Only the print statements change — echo $j . " " and echo $k . " ". Loop bounds and the k = i - 1 start stay the same as Example 1.
Set $rows = 5; and use fgets(STDIN) when reading input. Set loop variables $i, $j, $k.
for ($i = 1; $i <= $rows; $i++) — one palindrome row per iteration.
for ($j = 1; $j <= $i; $j++) — prints digits 1..i (left half).
for ($k = $i - 1; $k >= 1; $k--) — mirrors without repeating the peak.
echo PHP_EOL ends the row after both inner loops finish.
Each row mirrors itself — O(n²) time, O(1) extra memory.
rows = 5Trace each outer-loop value of i, the ascending and descending halves, and the full row output.
i | Ascending (j) | Descending (k) | Row output |
|---|---|---|---|
1 | 1 | (none) | 1 |
2 | 1, 2 | 1 | 121 |
3 | 1, 2, 3 | 2, 1 | 12321 |
4 | 1, 2, 3, 4 | 3, 2, 1 | 1234321 |
5 | 1, 2, 3, 4, 5 | 4, 3, 2, 1 | 123454321 |
Row length grows as 2i - 1 digits — total prints = n² for n 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: change k = i - 1 to k = i and watch the peak digit repeat.
Foundation for inverted, pyramid, diamond, and hollow variants.
Example: continue to Program 28 for a 0-centered descending mirror variant.
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 digits for rows = 5 → 1 + 3 + 5 + 7 + 9 = 25.
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 — the mirror starts at i - 1.
Small habits that keep number-pattern code clean.
Use j for ascending and k for descending — do not reuse the same variable for both halves.
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 rows = 3 on paper before coding larger demos.
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 palindrome number triangles.
Each digit lands on its own line — you get a column, not a triangle.
→ Use echo $j or echo $k; echo PHP_EOL only after both inner loops.
Starting k = i repeats the peak digit — e.g. 1221 instead of 121.
→ Use for ($k = $i - 1; $k >= 1; $k--) so the middle digit appears once.
Only the ascending half prints — rows look like 1, 12, 123 instead of palindromes.
→ Add the descending loop for ($k = $i - 1; $k >= 1; $k--) after the ascending loop.
Writing echo $i in an inner loop repeats the row number, not the sequence digit.
→ Print j in the ascending loop and k in the descending loop.
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 just 1 — the mirror loop does not run.
Outer loop never runs — print nothing or show a message.
rows < 0Treat as invalid; re-prompt instead of silent empty output.
Two rows: 1 and 121.
Unchecked fgets(STDIN) input leaves rows unset — call is_numeric(trim($line)) first.
Output grows as rows² digits — fine for labs, noisy for huge values.
Try these variations to lock in the pattern.
i == j swapecho $j . " " in both loops(char)('a' + j - 1) instead of digits1..i; descending loop prints i-1..1 — start mirror at i - 1, not i.echo stays on the line; echo PHP_EOL advances — mix them carefully.rows > 0 for interactive programs; rows = 1 prints a single 1.echo $j . " " in both loops for easier reading on wide rows.Quick Takeaway: outer loop $i = 1..$rows, ascending $j = 1..$i, descending $k = $i-1..1, then echo PHP_EOL.
| Program | Time | Extra space |
|---|---|---|
| Nested loops (Examples 1–3) | O(n²) | O(1) |
| Spaced output (Example 3) | O(n²) | O(1) |
The palindrome number triangle is a compact lesson in symmetry: print ascending 1..i, mirror with descending i-1..1, and end each row with echo PHP_EOL. Master the fixed-rows version, then try user input and spaced output.
Practice the three examples above, then continue to Program 28 for the 0-centered descending mirror pattern.
Start the mirror loop at i - 1, not i — validate rows when reading from the console.
for ($i = 1; $i <= $rows; $i++) in the outer loopfor ($j = 1; $j <= $i; $j++)for ($k = $i - 1; $k >= 1; $k--)is_numeric(trim($line)) before using rowsecho PHP_EOL inside either inner loopk = i (repeats peak)i instead of j or krows = 1 edge casePrint the pattern the beginner-friendly way.
1..i then i-1..1
DefinitionAscending
CodeMirror
CodeSame both ways
ShapeO(n²) time
AnalysisThis 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.
Move on to the 0-centered descending mirror number pattern in the PHP number-pattern series.
12 people found this page helpful