Alternating Number Triangle in PHP

Beginner
⏱️ 8 min read
📚 Updated: Aug 2026
🎯 3 Code Examples
🚀 Live Preview
Running Counter $k

What You’ll Learn

The alternating triangle prints 1, 3 2, 4 5 6, 10 9 8 7, 11 12 13 14 15 — numbers fill continuously but odd rows ascend and even rows descend. This tutorial covers running counter $k, row end $m, live preview, worked PHP examples, edge cases, and O(n²) complexity.

Shape Rule

$k / $m--

Odd rows print $k ascending; even rows print $m-- descending.

Running Counter

$k marches on

$k never resets — it tracks the next number across all rows.

Row End $m

$m = $k + $i - 1

Compute $m before each inner loop for even-row descending output.

Odd/Even Rows

$i % 2

Use $i % 2 == 1 to pick ascending vs descending print direction.

Live Preview

3–12 rows

Pick a row count and draw the alternating number triangle instantly in the browser.

O(n²)

Complexity

Total values ≈ n(n+1)/2 — work grows as n².

Introduction

An alternating ascending/descending number triangle fills numbers continuously from 1, but odd rows print ascending and even rows print descending. Row 2 shows 3 2; row 4 shows 10 9 8 7.

In PHP: outer for ($i = 1; $i <= $rows; $i++), set $m = $k + $i - 1, inner for ($j = 1; $j <= $i; $j++), if odd echo $k else echo $m--, increment $k, then echo PHP_EOL after the inner loop.

Why it matters?

It is a running-counter exercise that alternates print direction on odd and even rows.

Key Highlights

Outer loop $i

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

Counter + direction

$k ascending, $m descending prints ascending or descending each row.

Running Counter $k

$k tracks the next number; odd rows print $k, even rows print from $m downward.

Series Foundation

Follow Program 50 decreasing-increasing pattern; continue to Program 52 palindrome rows.

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

📝 Problem & Approach

Given $rows = 5, print five lines: 1, 3 2, 4 5 6, 10 9 8 7, 11 12 13 14 15.

PHP
// $rows = 5 (conceptual output)
// 1
// 3 2
// 4 5 6
// 10 9 8 7
// 11 12 13 14 15

Inputs & Outputs

ItemTypeDescription
$rowsintHow many lines to print (typically ≥ 1).
i, jintRow index $i; running counter $k and row end $m = $k + $i - 1.
Printed outputtext$i values on row $i — growing triangle shape.

Minimal workflow

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

Approach comparison

ApproachIdeaBest for
Running counter $kecho $k on odd rows, echo $m-- on even rowsGrowing triangle — $i values per row
fgets(STDIN) input(int) $input after is_numeric($input)User-chosen row count
No trailing spacePrint space only before 2nd+ valuesCleaner row formatting — Example 3

⚡ Quick Reference

GoalPattern
Set rows$rows = 5;
Outer loopfor ($i = 1; $i <= $rows; $i++)
Init counter$k = 1;
Row end$m = $k + $i - 1;
Inner loopfor ($j = 1; $j <= $i; $j++)
Odd/even printif ($i % 2 == 1) echo $k else echo $m--; then $k++
Row breakecho PHP_EOL; after inner loop
Program 50 contrastDecreasing-increasing pattern uses dual loops per row; this pattern uses running counter $k with odd/even direction

📋 Odd Row vs Even Row vs Combined

How outer row selection, running counter $k, row end $m, and odd/even direction work together.

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

Picks row number $i — triangle height.

Row end $m
$m = $k + $i - 1

Computed before the inner loop on each row.

Print direction
if ($i % 2 == 1) $k
else $m--

Odd rows ascending from $k; even rows descending from $m.

Learning tip
trace $i=4

Dry-run row 4: $k=7, $m=10 → prints 10 9 8 7.

Context

When This Pattern Shows Up

Reach for this pattern when teaching running counters, odd/even conditions, and alternating row direction.

  1. First lab exercise

    Classic follow-up after decreasing-increasing patterns like Program 50.

  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 50 (decreasing-increasing pattern), then continue to Program 52 (palindrome rows).

  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 running counters, parity checks, and O(n²) thinking.

🔮 Live Preview

Choose a row count and draw the alternating number triangle 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 no-trailing-space variant. Click View Output to reveal sample console results.

📚 Getting Started

Print five rows with running counter $k — odd rows ascending, even rows descending.

Example 1 — Fixed $rows = 5

Hard-coded size — compute $m = $k + $i - 1 and alternate print direction by row parity.

PHP
<?php
$rows = 5;
$k = 1;

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

How It Works

When $i = 4, $k = 7, $m = 10 — even row prints 10 9 8 7. Row 2 is even — values 2 and 3 print as 3 2.

📈 Practical Variant

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

Example 2 — fgets(STDIN) Input

Same $k/$m counter logic; 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;

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

How It Works

Identical counter logic to Example 1; only the row count is dynamic.

⚡ Formatting Variant

Avoid trailing spaces on each row.

Example 3 — No Trailing Space

Print a space only before the second and later values on each row.

PHP
<?php
$rows = 5;
$k = 1;

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

How It Works

Same counter logic; only the output format avoids trailing spaces.

🧠 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

Print by row parity

Set $m = $k + $i - 1. If $i is odd, echo $k; if even, echo $m--. Increment $k each inner step.

Direction
4

New line after row

echo PHP_EOL; after the inner loop moves to the next row.

Break
=

Alternating ascending/descending number triangle complete

Total prints ≈ n(n+1)/2O(n²) time, O(1) extra memory.

🔎 Worked Walkthrough — row i = 4

Trace row 4 with $rows = 5 to see how $k, $m, and even-row descending output build 10 9 8 7.

StepkmPrinted
Before row 47
Compute m710
j=1 (even row)8910
j=2989
j=31078
j=41167

Row output: 10 9 8 7. Then echo PHP_EOL moves to row 5 with k = 11.

Use Cases

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

1. Teaching Running Counter $k

Clearest visual proof that outer and inner bounds interact.

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

2. Odd/Even Direction Link

Each row alternates print direction while $k marches forward continuously.

Example: compare row 4 (10 9 8 7) — even row prints from m downward.

3. Console Formatting Drills

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

Example: use echo $k . " ") in both loops for spaced output — Example 3.

4. No Trailing Space

Print a space only before the second and later values on each row.

Example: print $rows=5 without trailing spaces and compare formatting.

5. Complexity Intuition

Growing inner bounds plus direction flip makes O(n²) concrete for beginners.

Example: count values for rows=5 → 1+2+3+4+5 = 15 printed numbers.

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

    Wrong odd/even direction shows immediately — even rows should print descending from $m.

  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 remove trailing spaces with conditional echo.

  4. 4. O(1) Extra Memory

    Streaming output needs no storage beyond loop counters.

Pro Tip: learn the running counter $k 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

    Compute $m, run inner loop with direction check, increment $k, then echo PHP_EOL.

  4. 4. Use echo for Values

    Use echo $k . " " or echo $m-- . " " inside the inner loop; one echo PHP_EOL per row after it finishes.

  5. 5. Dry-Run One Small n

    Trace $rows = 5, $i = 4 on paper — expect 10 9 8 7.

Pro Tip: if even rows look ascending, check whether you forgot $m = $k + $i - 1 or the odd/even condition.

Common Pitfalls

Mistakes that commonly break alternating ascending/descending number triangles.

  1. 1. echo PHP_EOL Inside an Inner Loop

    Each value lands on its own line — you get a column, not a triangle row.

    → Use echo $k or echo $m-- inside the inner loop; echo PHP_EOL only after it finishes.

  2. 2. Forgetting $m = $k + $i - 1

    Without computing $m before the inner loop, even rows cannot print descending correctly.

    → Always set $m = $k + $i - 1 before the inner loop on every row.

  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

    Resetting $k to 1 each row breaks the continuous number sequence.

    → Let $k continue across rows; only compute fresh $m each outer iteration.

  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 odd rows ascend and even rows descend

2. Flip direction

  • Swap the odd/even condition to flip directions
  • Observe how row 2 changes from 3 2 to 2 3

3. Reverse outer loop

  • Use for ($i = $rows; $i >= 1; $i--)
  • Print bottom row first

4. Next in series

  • Continue with Program 52 palindrome rows
  • Connect to palindromic row patterns

Notes

  • Value count. Total prints ≈ n(n+1)/2 (e.g. 15 values 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.
  • Odd rows use echo $k; even rows use echo $m-- — always increment $k each inner step.

Quick Takeaway: outer $i=1..$rows, $m=$k+$i-1, inner $j=1..$i, odd echo $k else echo $m--, $k++, 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)
No trailing space (Example 3)O(n²)O(1)
Wrap Up

🎉 Conclusion

The alternating triangle combines a running counter with odd/even row direction — a natural step after decreasing-increasing patterns. Master the fixed-$rows version first, then try fgets(STDIN) input and the no-trailing-space variant in Example 3.

Practice the three examples above, then continue to Program 52 for the increasing-decreasing palindrome pattern (1, 232, 34543…).

Keep echo PHP_EOL after the inner loop — one row break per outer iteration.

💡 Best Practices

✅ Do

  • Explain outer $i, running counter $k, row end $m = $k + $i - 1, and odd/even direction before coding
  • Use echo $k . " " or echo $m-- . " ", then echo PHP_EOL after inner loop
  • Validate $rows ≥ 1 for interactive programs
  • Check fgets(STDIN) return value before using $rows
  • State O(n²) time when asked about complexity

❌ Don’t

  • Reset $k each row (breaks continuous sequence)
  • Forget to compute $m = $k + $i - 1 before the inner loop
  • 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 alternating number triangle

Print the pattern the beginner-friendly way.

5
Core concepts
02

Outer loop

$i = 1..$rows

Code
03

Counter $k

Odd: echo $k; even: echo $m--

Logic
n 04

Growing rows

n(n+1)/2 prints

I/O
O 05

Complexity

O(n²)

Analysis

❓ Frequently Asked Questions

Row 2 is even, so values 2 and 3 are printed in reverse order as 3 2.
If $k is the next number to print, row $i contains $i values ending at $m = $k + $i - 1.
Row 4 starts at $k=7, so $m=10. Even rows print $m downward: 10, 9, 8, 7.
Yes. Use a variable $rows in the outer loop — the same $k/$m logic works for any positive n.
Echo a space only before the second and later values — see Example 3.
No. $k is a running counter that continues across all rows.
O(n²) for n rows. Total prints are 1+2+...+n = n(n+1)/2.
Use trim(fgets(STDIN)) and is_numeric($input) before casting to int.

Did you Know? 🔊

Numbers fill continuously from 1, but each row alternates print direction — odd rows ascending (4 5 6), even rows descending (10 9 8 7). Compute row end with $m = $k + $i - 1.

Continue to Program 52

Move on to the increasing-decreasing palindrome pattern in the PHP number-pattern series.

Program 52 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