Diagonal-Fill Triangle Number Pattern in PHP

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

What You’ll Learn

The diagonal-fill triangle starts each row with index $i, then generates remaining values using $res = $res + $k where $k begins at $rows - 1 and decreases. For $rows = 5: 1, 2 6, 3 7 10, 4 8 11 13, 5 9 12 14 15. This tutorial covers the step logic, live preview, worked PHP examples, edge cases, and O(n²) complexity.

Row Start

$res = $i

First value on row $i is always $i when $i == $j.

Step Variable

$k = $rows-1

$k starts at $rows-1 each row and decreases after each addition step.

Accumulator

$res + $k

After the first value, update $res = $res + $k and echo $res; then $k--.

Growing Rows

i values

Row $i prints exactly $i numbers — inner loop $j = $i..$i+$i-1.

Live Preview

3–12 for n

Pick size n and draw the full diagonal-fill triangle pattern instantly in the browser.

O(n²)

Complexity

Total prints = n(n+1)/2 — triangular growth, O(n²) time.

Introduction

A diagonal-fill number triangle starts each row with $i and builds the rest using decreasing step sizes. Row 2 becomes 2 6; row 3 becomes 3 7 10.

In PHP: outer for ($i = 1; $i <= $rows; $i++), set $k = $rows - 1 and $res = $i, inner for ($j = $i; $j < $i + $i; $j++) — echo $j when $i == $j, else $res = $res + $k, then echo PHP_EOL.

Why it matters?

It shows how a running total and a shrinking step fill a triangle without a 2D array — the same numbers as a column-wise fill, generated row by row.

Key Highlights

Row start

First value on row $i is $i when $i == $j.

Step $k

Starts at $rows - 1 each row, then $k--.

Accumulator

After the first value: $res = $res + $k.

Series Foundation

Follow Program 54; continue to Program 56 next.

In short: outer $i = 1..$rows; set $k = $rows - 1 and $res = $i; inner $j = $i..$i+$i-1 prints $j or $res + $k, then echo PHP_EOL.

📝 Problem & Approach

Given $rows = 5, print five lines with 1, 2, 3, 4, and 5 numbers respectively.

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

Inputs & Outputs

ItemTypeDescription
$rowsintNumber of triangle rows (typically ≥ 1).
$i, $j, $k, $resintRow $i; inner index $j; step $k; running total $res.
Printed outputtext$i numbers on row $i; total $rows($rows+1)/2 values.

Minimal workflow

Pseudocode
for $i from 1 to $rows:
    $k = $rows-1; $res = $i
    for $j from $i to $i+$i-1:
        if $i==$j: echo $j
        else: $res = $res+$k; echo $res; $k--
    echo PHP_EOL

Approach comparison

ApproachIdeaBest for
$res + $k stepping$res = $res + $k with $k decreasing each stepDiagonal-fill sequence within each row
implode rowBuild row without trailing spacesCleaner console output — Example 3
fgets(STDIN) input(int) $input for rowsUser-chosen row count
Compact outputimplode joins values with single spacesNo trailing space per row — Example 3

⚡ Quick Reference

GoalPattern
Set rows$rows = 5;
Outer loopfor ($i = 1; $i <= $rows; $i++)
Row setup$k = $rows - 1; $res = $i;
Inner loopfor ($j = $i; $j < $i + $i; $j++)
First valueif ($i == $j) echo $j
Next values$res = $res + $k; echo $res; $k--;
Row breakecho PHP_EOL; after each row
Program 54 contrastDiamond diagonal uses fixed-width rows; this triangle grows i values per row

📋 Row Start vs Step Logic vs Growing Triangle

How row start, step variable, inner bounds, and row breaks work together.

Row start
$res = $i
if ($i == $j) echo $j

First number on row $i is always $i.

Step logic
$k = $rows - 1
$res = $res + $k
$k--

Each subsequent value adds a shrinking step size.

Inner bounds
for ($j = $i; $j < $i + $i; $j++)

Row $i prints exactly $i numbers.

Learning tip
trace $i=3, $rows=5

Dry-run row 3: start 3, then +4→7, +3→10 → 3 7 10.

Context

When This Pattern Shows Up

Reach for this pattern when teaching step variables, running totals, and growing row lengths.

  1. First lab exercise

    Classic follow-up after diamond diagonal patterns — introduces step-based number generation.

  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 pattern size.

  4. Gateway to variants

    Compare with Program 54 (fixed-width diamond), then continue to Program 56 palindromic pyramid.

  5. Not a UI layout tool

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

Key benefit: one program that locks in step variables, running totals, and O(n²) thinking.

🔮 Live Preview

Choose pattern size n and draw the full diagonal-fill triangle number pattern in the browser.

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

Live result
Press "Draw pattern".

Examples Gallery

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

📚 Getting Started

Print five rows — each row grows by one number using $res + $k stepping.

Example 1 — Fixed $rows = 5

Hard-coded $rows = 5 — each row uses $res + $k stepping with $k = $rows - 1.

PHP
<?php
$rows = 5;

for ($i = 1; $i <= $rows; $i++) {
    $k = $rows - 1;
    $res = $i;

    for ($j = $i; $j < $i + $i; $j++) {
        if ($i == $j) {
            echo $j . " ";
        } else {
            $res = $res + $k;
            echo $res . " ";
            $k--;
        }
    }
    echo PHP_EOL;
}

How It Works

Row 1 prints just 1. Row 3 starts at 3, adds 4 to get 7, adds 3 to get 10 — output 3 7 10.

📈 Practical Variant

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

Example 2 — fgets(STDIN) Input

Same stepping logic; row count comes from user input.

PHP
<?php
echo "Enter 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++) {
    $k = $rows - 1;
    $res = $i;
    for ($j = $i; $j < $i + $i; $j++) {
        if ($i == $j) echo $j . " ";
        else {
            $res = $res + $k;
            echo $res . " ";
            $k--;
        }
    }
    echo PHP_EOL;
}

How It Works

Same stepping logic as Example 1; row count comes from fgets(STDIN) input.

⚡ Character Variant

Build each row with an array and implode — no trailing space.

Example 3 — Compact Rows

Same logic; use an array and implode to join values without a trailing space.

PHP
<?php
$rows = 5;

for ($i = 1; $i <= $rows; $i++) {
    $k = $rows - 1;
    $res = $i;
    $parts = [];

    for ($j = $i; $j < $i + $i; $j++) {
        if ($i == $j) $parts[] = $j;
        else {
            $res = $res + $k;
            $parts[] = $res;
            $k--;
        }
    }
    echo implode(" ", $parts) . PHP_EOL;
}

How It Works

Same stepping logic; implode on an array produces clean rows without trailing spaces.

🧠 How the Algorithm Fills Each Row

1

Set up

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

Setup
2

Outer loop

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

Loop
3

Init k and res

Each row: $k = $rows - 1, $res = $i — step size and running total reset.

Diagonals
4

Inner loop stepping

$j = $i..$i+$i-1: echo $j when $i==$j, else $res += $k and $k--; then echo PHP_EOL.

Break
=

Diagonal-fill triangle complete

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

🔎 Worked Walkthrough — row $i = 3, $rows = 5

Trace row 3 to see how $res + $k stepping produces 3 7 10.

StepjAction / row so far
Start$k=4, $res=3
First3$i==$j → echo 3 → 3
Second4$res=3+4=7, $k=3 → 3 7
Third5$res=7+3=10, $k=2 → 3 7 10

Final row 3 output: 3 7 10. Then echo PHP_EOL moves to row 4.

Use Cases

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

1. Teaching $res + $k Steps

Clearest visual proof that outer and inner bounds interact.

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

2. Decreasing Step Sizes

$k starts at $rows-1 and decreases — controls how far each step jumps.

Example: trace row 3 with rows=5 — 3, then +4→7, +3→10.

3. Console Formatting Drills

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

Example: use implode for clean rows — see Example 3.

4. Triangular Numbers

Last value on row n is always the triangular number n(n+1)/2.

Example: rows=5 ends with 15 — total count of printed numbers.

5. Complexity Intuition

Total prints n(n+1)/2 makes O(n²) concrete for beginners.

Example: count values for rows=5 → 1+2+3+4+5 = 15 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

    Wrong step logic shows immediately — row values grow too fast or too slow.

  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 join values with implode for compact rows.

  4. 4. O(1) Extra Memory

    Streaming output needs no storage beyond loop counters.

Pro Tip: learn the $res + $k stepping first; then try fgets(STDIN) input and the implode 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/$k/$res for loop variables.

  2. 2. Prefer fgets(STDIN)

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

  3. 3. Row Break After Inner Loop

    Finish the inner loop for row $i, then call echo PHP_EOL.

  4. 4. Reset k Each Row

    Set $k = $rows - 1 and $res = $i at the start of every outer iteration.

  5. 5. Dry-Run One Small rows

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

Pro Tip: if row values grow too fast, check whether $k-- runs after each $res + $k step.

Common Pitfalls

Mistakes that commonly break diagonal-fill triangle number patterns.

  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 inside the inner loop; echo PHP_EOL only after it finishes.

  2. 2. Forgetting to Decrement k

    If $k never decreases, every step adds the same offset — row values grow too fast.

    → Call $k-- after each $res = $res + $k update.

  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 Inside Inner Loop Only

    $k must reset to $rows - 1 at the start of each outer row, not once globally.

    → Place $k = $rows - 1 inside the outer loop, before the inner loop.

  5. 5. Unchecked fgets(STDIN) Input

    Letters or empty input throw invalid input without validation.

    → Use is_numeric($input) before (int) $input.

  6. 6. Hard-coding 5 Everywhere

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

    → Use one $rows variable for outer loop and $k initialization.

Edge Cases

Check these inputs before calling the solution done.

rows = 1

Single line

Output is one line: 1 — the inner loop prints a single value.

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 rows

Large rows

Large values produce wide rows — 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 n

  • Try $rows = 3, 6, or 8
  • Verify row i prints exactly i numbers

2. implode rows

  • Build each row without trailing spaces
  • Compare print-based vs implode output

3. Step size experiment

  • Try starting $k = $rows instead of $rows - 1
  • Observe how row values shift

4. Next in series

  • Continue with Program 56 palindromic pyramid
  • Try rows=6 and trace the last value (triangular number 21)

Notes

  • Cell count. Total prints = $rows($rows+1)/2 (e.g. 15 numbers for $rows=5).
  • echo stays on the line; echo PHP_EOL advances — mix them carefully.
  • Validate $rows > 0 for interactive programs; $rows = 1 prints one number.
  • Step logic: if ($i==$j) echo $j; else $res = $res + $k; echo $res; $k--;.

Quick Takeaway: outer $i=1..$rows, $k=$rows-1, $res=$i; inner $j=$i..$i+$i-1; step with $res+$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)
Compact rows (Example 3)O(n²)O(1)
Wrap Up

🎉 Conclusion

The diagonal-fill triangle combines a growing inner loop with decreasing step sizes — a natural step after fixed-width diamond patterns. Master the fixed-$rows version first, then try fgets(STDIN) input and the compact implode variant in Example 3.

Practice the three examples above, then continue to Program 56 for the palindromic number pyramid pattern.

Reset $k = $rows - 1 and $res = $i at the start of every row — one echo PHP_EOL per outer iteration.

💡 Best Practices

✅ Do

  • Explain outer $i, $res + $k stepping, and inner bounds before coding
  • Reset $k = $rows - 1 and $res = $i at the start of each row; then echo PHP_EOL
  • Validate $rows ≥ 1 for interactive programs
  • Check fgets(STDIN) return value before using $rows
  • State O(n²) time when asked about complexity

❌ Don’t

  • Forget to reset $k = $rows - 1 each row
  • Skip k-- after each step
  • 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 diagonal-fill triangle pattern

Start each row at $i, then add shrinking steps via $res + $k.

5
Core concepts
02

Outer loop

$i = 1..$rows

Code
03

Step variable

$k starts at $rows-1

Logic
n 04

Row length

$i values per row

I/O
O 05

Complexity

O(n²)

Analysis

❓ Frequently Asked Questions

Row 2 starts at 2 (when $i==$j). Next value: $res=2+4=6 because $k starts at $rows-1=4.
$k starts at $rows-1 each row and decreases after each step. It is the offset added to $res for the next number.
With 5 rows you print 1+2+3+4+5=15 numbers total — 15 is the final value on the last row.
Yes. Use a variable $rows and set $k = $rows - 1 at the start of each row.
Exactly $i numbers — the inner loop runs from $j = $i to $j < $i + $i.
Collect values in an array and echo implode(' ', $parts) — see Example 3.
O(n²) for n rows because you print n(n+1)/2 numbers in total.
Use trim(fgets(STDIN)) and is_numeric($input) before casting to int.

Did you Know? 🔊

Each row starts with index $i, then adds decreasing step sizes via $res = $res + $k where $k starts at $rows - 1. Row $i prints exactly $i numbers.

Continue to Program 56

Move on to the palindromic number pyramid pattern in the PHP number-pattern series.

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