Increasing-Decreasing Palindrome Rows in PHP

Beginner
⏱️ 8 min read
📚 Updated: Aug 2026
🎯 3 Code Examples
🚀 Live Preview
Dual Inner Loops

What You’ll Learn

The palindrome row pattern prints 1, 232, 34543, 4567654, 567898765 — each row increases then mirrors downward. This tutorial covers dual inner-loop logic, the $m = $m - 2 center step, live preview, worked PHP examples, edge cases, and O(n²) complexity.

Shape Rule

$m++ / $m--

Row $i: increase $i digits, then decrease $i-1 digits.

Row Start

$m = $i

Each row begins at its row number — row 4 starts from 4.

Center Step

$m = $m - 2

Between loops, step back so the peak digit is not printed twice.

Palindrome Width

2i - 1 digits

Row $i has 2*$i-1 digits — width grows each line.

Live Preview

3–12 rows

Pick a row count and draw the palindrome row pattern instantly in the browser.

O(n²)

Complexity

Total digits ≈ — work grows quadratically.

Introduction

An increasing-decreasing palindrome row pattern starts each row at $i, prints an increasing run, then mirrors downward. Row 3 gives 34543; row 4 gives 4567654.

In PHP: outer for ($i = 1; $i <= $rows; $i++), $m = $i, inner increase loop echo $m++, $m = $m - 2, inner decrease loop echo $m--, then echo PHP_EOL after both inner loops.

Why it matters?

It is a dual inner-loop exercise that builds palindrome-like rows with increase then decrease segments.

Key Highlights

Outer loop $i

$i = 1..$rows picks each row number.

Increase + decrease

First loop echo $m++; after $m = $m - 2, second loop echo $m--.

Dual Inner Loops

Each row resets $m = $i — increase loop then decrease loop per row.

Series Foundation

Follow Program 51 alternating triangle; continue to Program 53 diagonal mirror.

In short: outer $i=1..$rows, $m=$i, inner $j=1..$i echo $m++, $m=$m-2, inner $k=1..$i-1 echo $m--, then echo PHP_EOL.

📝 Problem & Approach

Given $rows = 5, print five lines: 1, 232, 34543, 4567654, 567898765.

PHP
// $rows = 5 (conceptual output)
// 1
// 232
// 34543
// 4567654
// 567898765

Inputs & Outputs

ItemTypeDescription
$rowsintHow many lines to print (typically ≥ 1).
$i, $j, $k, $mintRow index $i; variable $m with increase loop and decrease loop.
Printed outputtext2*$i-1 digits on row $i — palindrome-like width.

Minimal workflow

Pseudocode
for i from 1 to rows:
    $m = $i
    for j from 1 to i: print m; m = m + 1
    $m = $m - 2
    for k from 1 to i-1: print m; m = m - 1
    newline

Approach comparison

ApproachIdeaBest for
Dual inner loopsecho $m++ then echo $m-- with $m = $m - 2 betweenPalindrome width — 2*$i-1 digits per row
fgets(STDIN) input(int) $input after is_numeric($input)User-chosen row count
Spaced digitsPrint space after each digit in both loopsEasier reading for wider rows — Example 3

⚡ Quick Reference

GoalPattern
Set rows$rows = 5;
Outer loopfor ($i = 1; $i <= $rows; $i++)
Row start$m = $i;
Increase loopfor ($j = 1; $j <= $i; $j++) echo $m++;
Center step$m = $m - 2;
Decrease loopfor ($k = 1; $k < $i; $k++) echo $m--;
Row breakecho PHP_EOL; after both inner loops
Program 51 contrastAlternating triangle uses running counter $k; this pattern uses dual inner loops with $m = $m - 2

📋 Increase Loop vs Decrease Loop vs Combined

How outer row selection, increase loop, center step, and decrease loop work together.

Outer loop
for ($i = 1; $i <= $rows; $i++)

Picks row number $i — also the starting digit.

Increase loop
$m = $i
for ($j = 1; $j <= $i; $j++)
  echo $m++

Prints $i ascending digits on row $i.

Decrease loop
$m = $m - 2
for ($k = 1; $k < $i; $k++)
  echo $m--

Prints i-1 descending digits — mirrors without duplicating peak.

Learning tip
trace $i=3

Dry-run row 3: increasing 345 + decreasing 4334543.

Context

When This Pattern Shows Up

Reach for this pattern when teaching dual inner loops, palindrome rows, and the $m = $m - 2 center step.

  1. First lab exercise

    Classic follow-up after alternating triangle patterns like Program 51.

  2. Nested-loop warm-up

    Outer/inner bound practice with an immediate visual check.

  3. Console I/O practice

    Combine loops with fgets(STDIN) for a flexible row count.

  4. Gateway to variants

    Compare with Program 51 (alternating triangle), then continue to Program 53 (diagonal mirror).

  5. Not a UI layout tool

    This is a console teaching pattern — not how you build modern app screens.

Key benefit: one small program that locks in dual inner loops, $m = $m - 2, and O(n²) thinking.

🔮 Live Preview

Choose a row count and draw the palindrome row pattern in the browser.

Try 3, 5, or 8 rows (up to 12).

Live result
Press "Draw pattern".

Examples Gallery

Three complete PHP programs — fixed $rows = 5, fgets(STDIN) input, and a spaced-digit variant. Click View Output to reveal sample console results.

📚 Getting Started

Print five rows with increase then decrease loops — palindrome-like rows.

Example 1 — Fixed $rows = 5

Hard-coded size — start $m = $i, increase loop, $m = $m - 2, then decrease loop.

PHP
<?php
$rows = 5;

for ($i = 1; $i <= $rows; $i++) {
    $m = $i;

    for ($j = 1; $j <= $i; $j++) {
        echo $m++;
    }

    $m = $m - 2;
    for ($k = 1; $k < $i; $k++) {
        echo $m--;
    }

    echo PHP_EOL;
}

How It Works

When $i = 3, increasing prints 345, then $m = $m - 2 gives decreasing 43 — output 34543. Row 1 has only the increasing half — output is 1.

📈 Practical Variant

Read $rows with fgets(STDIN) for flexible output size.

Example 2 — fgets(STDIN) Input

Same dual inner loops; row count comes from user input.

PHP
<?php
echo "Enter the number of rows: ";
$input = trim(fgets(STDIN));
if (!is_numeric($input)) {
    echo "Invalid input." . PHP_EOL;
    exit(1);
}
$rows = (int) $input;

for ($i = 1; $i <= $rows; $i++) {
    $m = $i;
    for ($j = 1; $j <= $i; $j++) echo $m++;
    $m = $m - 2;
    for ($k = 1; $k < $i; $k++) echo $m--;
    echo PHP_EOL;
}

How It Works

Identical loop structure to Example 1; only the row count is dynamic.

⚡ Formatting Variant

Add spaces between digits for easier reading.

Example 3 — Spaced Digits

Print a space after each digit in both inner loops.

PHP
<?php
$rows = 5;

for ($i = 1; $i <= $rows; $i++) {
    $m = $i;

    for ($j = 1; $j <= $i; $j++) {
        echo $m++ . " ";
    }

    $m = $m - 2;
    for ($k = 1; $k < $i; $k++) {
        echo $m-- . " ";
    }

    echo PHP_EOL;
}

How It Works

Same dual-loop logic; only the output format adds spaces between digits.

🧠 How the Algorithm Prints Rows

1

Set up

echo is built in; use fgets(STDIN) when reading input. Set $rows (e.g. 5).

Setup
2

Loop rows

for ($i = 1; $i <= $rows; $i++) — one iteration per output line.

Loop
3

Increase then decrease

First loop echo $m++ for $i steps; after $m = $m - 2, second loop echo $m-- for $i-1 steps.

Dual loop
4

New line after row

echo PHP_EOL; after both inner loops moves to the next row.

Break
=

Increasing-decreasing palindrome row pattern complete

Total prints ≈ digits — O(n²) time, O(1) extra memory.

🔎 Worked Walkthrough — row $i = 3

Trace row 3 to see how increase, $m = $m - 2, and decrease build 34543.

Phase$mRow so far
Start3
Increase $j=1,2,36345
$m = $m - 24345
Decrease $k=133454
Decrease $k=2234543

After both inner loops, echo PHP_EOL moves to the next row.

Use Cases

Where this tiny pattern (and its loop structure) shows up beyond the homework prompt.

1. Teaching Dual Inner Loops

Clearest visual proof that outer and inner bounds interact.

Example: use fgets(STDIN) for dynamic row count — see Example 2.

2. $m = $m - 2 Link

Each row mirrors after the peak — $m = $m - 2 prevents duplicating the center digit.

Example: compare row 3 (34543) — increasing 345 plus decreasing 43.

3. Console Formatting Drills

Practice echo vs PHP_EOL for multi-line vs single-line output.

Example: use echo $m++ . " " in both loops for spaced output — Example 3.

4. Spaced Output

Add spaces after each digit in both inner loops for readability.

Example: print $rows=5 with spaced output and compare readability.

5. Complexity Intuition

Palindrome width 2i-1 makes O(n²) concrete for beginners.

Example: count digits for rows=5 → 1+3+5+7+9 = 25 prints.

6. Input Validation Labs

Pair the pattern with fgets(STDIN) and positive-row checks.

Example: reject rows <= 0 and re-prompt.

Pro Tip: when an interviewer asks for patterns, explain the outer/inner loop roles first — then write the loops. The story matters as much as the code.

Advantages

Why this pattern earns a permanent spot in beginner PHP courses.

  1. 1. Instant Visual Feedback

    Missing $m = $m - 2 shows immediately — center digit appears twice in each row.

  2. 2. Minimal Concepts

    Only loops and console output — no arrays or math libraries.

  3. 3. Easy to Extend

    Change $rows, use fgets(STDIN), or add spaces between digits in both inner loops.

  4. 4. O(1) Extra Memory

    Streaming output needs no storage beyond loop counters.

Pro Tip: learn the dual inner loops first; then try fgets(STDIN) input and the spaced-digit variant in Example 3.

Usage Tips

Small habits that keep number-pattern code clean.

  1. 1. Name Variables Clearly

    Use $rows for height and $i/$j for row/column indices.

  2. 2. Prefer fgets(STDIN)

    Avoid crashes when the user types letters instead of a number.

  3. 3. Row Break After Inner Loop

    Run increase loop, apply $m = $m - 2, run decrease loop, then echo PHP_EOL.

  4. 4. Use echo for Values

    Use echo $m++ and echo $m-- in the inner loops; one echo PHP_EOL per row after both loops.

  5. 5. Dry-Run One Small n

    Trace $rows = 5, $i = 3 on paper — expect 34543.

Pro Tip: if rows have duplicated center digits, check whether you forgot $m = $m - 2.

Common Pitfalls

Mistakes that commonly break increasing-decreasing palindrome row patterns.

  1. 1. echo PHP_EOL Inside an Inner Loop

    Each digit lands on its own line — you get a column, not a palindrome row.

    → Use echo $m++ or echo $m-- inside the inner loops; echo PHP_EOL only after they finish.

  2. 2. Forgetting $m = $m - 2

    Without $m = $m - 2, the peak digit prints twice — row 3 becomes 345543 instead of 34543.

    → Always apply $m = $m - 2 between the increase and decrease loops.

  3. 3. Forgetting the Row Break

    Omitting echo PHP_EOL after the inner loop glues all rows onto one line.

    → Always call echo PHP_EOL after the inner loop completes.

  4. 4. Resetting k Each Row

    Using k <= i in the decrease loop duplicates the peak digit.

    → Use $k < $i for the decrease loop — exactly i-1 descending digits.

  5. 5. Unchecked fgets(STDIN) Input

    Letters or empty input fail without validation.

    → Call is_numeric($input) before casting to (int).

  6. 6. Hard-coding 10 Everywhere

    Using literal 10 in loop bounds instead of variable $rows breaks dynamic input.

    → Use one $rows variable for the outer loop bound.

Edge Cases

Check these inputs before calling the solution done.

$rows = 1

Single line

Output is one line: 1.

$rows = 0

Empty pattern

Loop never runs — print nothing or show a message.

Negative

rows < 0

Treat as invalid; re-prompt instead of silent empty output.

Large n

Many rows

Large row counts produce many values — fine for labs; use smaller n for quick demos.

Bad input

Non-numeric fgets(STDIN) input

Unchecked fgets(STDIN) input leaves $rows unset — call is_numeric($input) first.

Compact

Single-line form

Use conditional spacing to avoid trailing spaces — see Example 3.

🎯 Practice Problems

Try these variations to lock in the pattern.

1. Change rows

  • Try $rows = 3, 6, or 8
  • Verify each row has 2i-1 digits and mirrors after the peak

2. Change row start

  • Try $m = $i * i instead of $m = $i
  • Observe how row sequences change

3. Increase only

  • Skip the decrease loop entirely
  • Compare palindrome row vs increasing-only output

4. Next in series

  • Continue with Program 53 diagonal mirror
  • Connect to diagonal mirror patterns

Notes

  • Digit count. Total prints ≈ (e.g. 25 digits for rows=5).
  • echo stays on the line; PHP_EOL advances — mix them carefully.
  • Validate $rows > 0 for interactive programs; $rows = 1 prints one value.
  • Increase loop uses echo $m++; after $m = $m - 2, decrease loop uses echo $m-- with $k < $i.

Quick Takeaway: outer $i=1..$rows, $m=$i, inner $j=1..$i echo $m++, $m=$m-2, inner $k=1..$i-1 echo $m--, then echo PHP_EOL.

⏱️ Time and Space Complexity

ProgramTimeExtra space
Fixed $rows = 5 (Example 1)O(n²)O(1)
fgets(STDIN) input (Example 2)O(n²)O(1)
Spaced digits (Example 3)O(n²)O(1)
Wrap Up

🎉 Conclusion

The palindrome row pattern combines dual inner loops with $m = $m - 2 — a natural step after alternating triangle patterns. Master the fixed-$rows version first, then try fgets(STDIN) input and the spaced-digit variant in Example 3.

Practice the three examples above, then continue to Program 53 for the diagonal mirror number pattern.

Keep echo PHP_EOL after both inner loops — one row break per outer iteration.

💡 Best Practices

✅ Do

  • Explain outer $i, $m = $i, increase loop, $m = $m - 2, and decrease loop before coding
  • Use echo $m++ and echo $m--, then echo PHP_EOL after both inner loops
  • Validate $rows ≥ 1 for interactive programs
  • Check fgets(STDIN) return value before using $rows
  • State O(n²) time when asked about complexity

❌ Don’t

  • Use k <= i in decrease loop (duplicates peak)
  • Forget $m = $m - 2 between the two inner loops
  • Hard-code 5 instead of variable $rows
  • Ignore bad console input in user-facing demos
  • Skip the $rows = 1 edge case

Key Takeaways

Knowledge Unlocked

Five things to remember about this palindrome row pattern

Print the pattern the beginner-friendly way.

5
Core concepts
02

Outer loop

$i = 1..$rows

Code
03

Variable $m

Up: echo $m++; down: echo $m--

Logic
n 04

Palindrome width

2*$i-1 digits/row

I/O
O 05

Complexity

O(n²)

Analysis

❓ Frequently Asked Questions

Row 3 prints increasing 345, then after $m = $m - 2 the decreasing part prints 43 — combined: 34543.
After the increasing loop, $m is one past the last printed value. $m = $m - 2 moves back to the previous digit so the peak is not duplicated.
The decreasing half has $i-1 digits — one less than the increasing half to avoid repeating the center.
Yes. Use a variable $rows in the outer loop — the same two-loop structure works for any positive n.
Echo a space after each digit in both inner loops — see Example 3.
Row $i prints 2*$i-1 digits — a palindrome-like width that grows each line.
O(n²) for n rows. Row $i prints 2*$i-1 digits; total work grows quadratically.
Use trim(fgets(STDIN)) and is_numeric($input) before casting to int.

Did you Know? 🔊

Each row starts from $i, prints an increasing run of length $i, then a decreasing run of length $i-1. The key step is $m = $m - 2 so the peak digit is not duplicated — row 3 gives 34543.

Continue to Program 53

Move on to the diagonal mirror number pattern in the PHP number-pattern series.

Program 53 tutorial →

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