Concentric Number Diamond Pattern in PHP

Beginner
⏱️ 8 min read
📚 Updated: Aug 2026
🎯 3 Code Examples
🚀 Live Preview
Nested Loops + Mirror

What You’ll Learn

The concentric number diamond prints a full symmetric shape: top half $i = $k..1, bottom mirror $i = 2..$k, each cell from max($i, $j). This tutorial covers both outer loops, live preview, algorithm steps, worked PHP examples, edge cases, and complexity.

Shape Rule

max($i,$j)

Print $j when $j > $i; otherwise $i — same rule as Program 46, applied to both halves.

Top Half

$i = $k..1

for ($i = $k; $i >= 1; $i--) shrinks toward the center row.

Bottom Mirror

$i = 2..$k

for ($i = 2; $i <= $k; $i++) expands back out — skips $i=1 to avoid duplicating center.

Row Columns

$j = $k..1, 2..$k

Each row uses left $j=$k..1 and right $j=2..$k2*$k-1 values per row.

Live Preview

k = 3–8

Pick a value for k and draw the full concentric number diamond in the browser.

O(k²)

Complexity

Prints (2*$k-1)² values total — e.g. 81 for $k=5; memory stays O(1).

Introduction

A concentric number diamond pattern shrinks toward the center, then expands back symmetrically. With $k = 5, you get 2*$k-1 = 9 rows; the center row is 5 4 3 2 1 2 3 4 5.

In PHP you run a top-half loop ($i = $k..1), then a bottom mirror ($i = 2..$k). Each row prints max($i, $j) over left and right column loops.

Why it matters?

It extends Program 46 with one mirror loop — the classic two-halves diamond technique.

Key Highlights

Top Half

$i = $k..1 — shrink toward center.

Bottom Mirror

$i = 2..$k — expand without repeating center.

max($i,$j) Rule

Same cell rule in every row of both halves.

Series Foundation

Follow Program 46 concentric square; continue to Program 48 powers of 11.

In short: top loop $i=$k..1, bottom loop $i=2..$k, each row prints max($i,$j), then echo PHP_EOL.

📝 Problem & Approach

Given $k = 5, print a full diamond: top half $i=$k..1, bottom mirror $i=2..$k, each cell max($i,$j).

PHP
// k = 5 (conceptual shape)
// 5 5 5 5 5 5 5 5 5
// 5 4 4 4 4 4 4 4 5
// 5 4 3 3 3 3 3 4 5
// 5 4 3 2 2 2 3 4 5
// 5 4 3 2 1 2 3 4 5
// 5 4 3 2 2 2 3 4 5
// 5 4 3 3 3 3 3 4 5
// 5 4 4 4 4 4 4 4 5
// 5 5 5 5 5 5 5 5 5

Inputs & Outputs

ItemTypeDescription
kintMaximum value and row count (typically ≥ 1).
Printed outputtext2*$k-1 rows, each with 2*$k-1 space-separated numbers.

Minimal workflow

Pseudocode
for $i from $k down to 1:
    for $j from $k down to 1:
        print max($i, $j)
    for $j from 2 to $k:
        print max($i, $j)
    print newline
for $i from 2 to $k:
    for $j from $k down to 1:
        print max($i, $j)
    for $j from 2 to $k:
        print max($i, $j)
    print newline

Approach comparison

ApproachIdeaBest for
Two outer loops + max rule$j > $i ? $j : $i in both halvesLearning and interviews
User-input k(int) $input after is_numeric();Flexible console programs
printRow helpermax($i,$j) in both loopsCleaner production-style code

⚡ Quick Reference

GoalPattern
Walk rows (top)for ($i = $k; $i >= 1; $i--)
Walk rows (bottom)for ($i = 2; $i <= $k; $i++)
Left halffor ($j = $k; $j >= 1; $j--)
Right halffor ($j = 2; $j <= $k; $j++)
Value rule$j > $i ? $j : $i or max($i, $j)
End the rowecho PHP_EOL;
Program 46 contrastConcentric square prints top $k rows only; this diamond mirrors with $i=2..$k

📋 Top Half vs Bottom Half vs Combined

Same diamond row — how top and bottom outer loops reuse the max($i,$j) rule.

Top half
$i = $k..1

Left segment $j=$k..1 before the mirror

Bottom mirror
$i = 2..$k

Right segment j=2..k completes each row

Value rule
max($i,$j)

Print $j when $j > $i; otherwise print $i

Learning tip
trace $i=3,$j=2

Dry-run cell (3,2): max(3,2) → prints 3

Context

When This Pattern Shows Up

Reach for this pattern when teaching max($i,$j) inside mirrored column loops.

  1. First lab exercise

    Classic follow-up after concentric diamonds and series patterns.

  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 46 (concentric square), then continue to Program 48 (powers of 11).

  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 nested loops, output sequencing, and O(k²) thinking.

🔮 Live Preview

Choose a value for k and draw the concentric number diamond in the browser.

Try 3, 5, or 7 for k (up to 8).

Live result
Press "Draw pattern".

Examples Gallery

Three complete PHP programs — fixed k, fgets(STDIN) input, and a printRow helper variant. Click View Output to reveal sample console results.

📚 Getting Started

Print nine rows for k=5 — top half plus mirrored bottom.

Example 1 — Fixed k = 5

Two outer loops — top $i=$k..1 and bottom $i=2..$k — with the same inner max rule.

PHP
<?php
$k = 5;

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

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

How It Works

The first loop prints rows 5 down to 1; the second loop prints rows 2 up to 5. Starting the bottom at $i = 2 keeps the center row from printing twice.

📈 Practical Variant

Let the user choose k at runtime.

Example 2 — User Input Version

Read k with fgets(STDIN) with is_numeric() (use is_numeric($input) in real apps).

PHP
<?php
echo "Enter k (e.g., 5): ";
$input = trim(fgets(STDIN));
if (!is_numeric($input)) {
    echo "Invalid input." . PHP_EOL;
    exit(1);
}
$k = (int) $input;

for ($i = $k; $i >= 1; $i--) {
    for ($j = $k; $j >= 1; $j--) echo ($j > $i ? $j : $i) . " ";
    for ($j = 2; $j <= $k; $j++) echo ($j > $i ? $j : $i) . " ";
    echo PHP_EOL;
}

for ($i = 2; $i <= $k; $i++) {
    for ($j = $k; $j >= 1; $j--) echo ($j > $i ? $j : $i) . " ";
    for ($j = 2; $j <= $k; $j++) echo ($j > $i ? $j : $i) . " ";
    echo PHP_EOL;
}

How It Works

Same nested-loop core as Example 1; only the source of k changes. Non-numeric input fails is_numeric($input) — validate before casting to int for safer labs.

⚡ Readability Variant

Extract row printing into a helper to avoid duplicating four inner loops.

Example 3 — printRow Helper

One printRow($i, $k) function — both outer loops call it.

PHP
<?php
function printRow($i, $k) {
    for ($j = $k; $j >= 1; $j--) echo max($i, $j) . " ";
    for ($j = 2; $j <= $k; $j++) echo max($i, $j) . " ";
    echo PHP_EOL;
}

$k = 5;

for ($i = $k; $i >= 1; $i--) printRow($i, $k);
for ($i = 2; $i <= $k; $i++) printRow($i, $k);

How It Works

printRow encapsulates the left/right inner loops and row break — both outer loops stay short and readable.

🧠 How the Algorithm Prints Rows

1

Set up

echo is built in; use fgets(STDIN) when reading input. Set $k (fixed or from input).

Setup
2

Top half loop

for ($i = $k; $i >= 1; $i--) — shrinks toward the center row.

Top
3

max($i,$j) per row

Left $j=$k..1 and right $j=2..$k print max($i,$j), then echo PHP_EOL.

Cells
4

Bottom mirror loop

for ($i = 2; $i <= $k; $i++) — expands back out; skips center duplicate.

Mirror
=

Concentric number diamond pattern complete

Total values printed ≈ (2*$k-1)²O($k²) time, O(1) extra memory.

🔎 Worked Walkthrough — why bottom half starts at $i = 2

Trace the mirror boundary to see why the center row is not duplicated.

CheckResultPrints
Top half ends$i = 1center row printed once
Bottom half starts$i = 2avoids duplicate center
Total rows2*$k-19 when $k=5

Full diamond: 2*$k-1 = 9 rows and 9 values per row when $k=5.

Use Cases

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

1. Teaching Nested Loops

Clearest visual proof that outer and inner bounds interact.

Example: use max($i,$j) instead of if-else — see Example 3.

2. Pattern Series Base

Foundation for concentric layouts, symmetric grids, and distance-based rules.

Example: swap max for min(i,j) to explore a different shape.

3. Console Formatting Drills

Practice echo.print vs row newline without complex math.

Example: put echo PHP_EOL inside the inner loop by mistake.

4. Character Substitution

Swap numbers for letters or stars once the max rule works.

Example: print row numbers with leading spaces for alignment.

5. Complexity Intuition

Grid totals make O(k²) concrete for beginners.

Example: count values for k=5 → 9 rows × 9 values = 81 prints.

6. Input Validation Labs

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

Example: reject k <= 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.

Advantages

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

  1. 1. Instant Visual Feedback

    Wrong mirror bounds (starting right half at 1) duplicate the center value.

  2. 2. Minimal Concepts

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

  3. 3. Easy to Extend

    Change k, swap max for min, or extract printRow for cleaner code.

  4. 4. O(1) Extra Memory

    Streaming output needs no storage beyond loop counters.

Pro Tip: learn the top and bottom mirror loops first; then try the printRow helper in Example 3.

Usage Tips

Small habits that keep number-pattern code clean.

  1. 1. Name Bounds Clearly

    Use k for the outer bound and keep i/j for row/column — or rename to row/col.

  2. 2. Prefer fgets(STDIN)

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

  3. 3. Keep echo PHP_EOL Outside

    Only call echo PHP_EOL after the inner loop finishes the row.

  4. 4. Use Ternary for Compact Code

    Compact: echo max($i, $j) + " "); in both inner loops.

  5. 5. Dry-Run One Small n

    Trace k = 3 on paper before coding larger demos.

Pro Tip: if the output is a vertical list of numbers per line, you almost certainly put echo PHP_EOL inside the inner loop.

Common Pitfalls

Mistakes that commonly break concentric number diamond patterns.

  1. 1. echo PHP_EOL Inside the Inner Loop

    Each number lands on its own line — you get a column, not a symmetric row.

    → Use echo.print for each value; echo PHP_EOL only after both inner loops finish.

  2. 2. Bottom Half Starts at $i = 1

    Starting the mirror loop at $i = 1 prints the center row twice in the full diamond.

    → Keep for ($i = 2; $i <= $k; $i++) for the bottom half.

  3. 3. Wrong Right-Half Start (Inner Loop)

    Starting the right inner loop at $j = 1 prints the center value twice on every row.

    → Keep for (j = 2; j <= k; j++) so the center appears once per row.

  4. 4. Forgetting the Row Break

    Omitting echo PHP_EOL glues every row onto one endless line.

    → Always end the row after both inner loops complete.

  5. 5. Unchecked fgets(STDIN) input

    Letters or empty input leave $k unset.

    → Use is_numeric($input) and re-prompt on failure.

  6. 6. Hard-coding 5 everywhere

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

    → Use one k variable for the outer bound and both inner loops.

Edge Cases

Check these inputs before calling the solution done.

k = 1

Single row

Output is one row of 2*$k-1 numbers; for $k=1 you get a single 1.

k = 0

Empty pattern

Outer loop never runs — print nothing or show a message.

Negative

k < 0

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

Large n

Large k

Output grows with $k rows and 2*$k-1 values per row — fine for labs, noisy for huge $k.

Bad input

Non-numeric fgets(STDIN) input

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

Compact

max() form

Use max($i,$j) for cleaner code — see Example 3.

🎯 Practice Problems

Try these variations to lock in the pattern.

1. Change k

  • Try $k = 3 or $k = 4 — count 2*$k-1 rows
  • Verify center row prints once

2. Compare with Program 46

  • Print only top half (drop second outer loop)
  • See how mirror completes the diamond

3. printRow refactor

  • Extract helper like Example 3
  • Add trailing-space trim with StringBuilder

4. Next in series

  • Continue with Program 48 powers of 11
  • Try min(i,j) for a different shape

Notes

  • Value count. Total numbers printed ≈ (2*$k-1)² (e.g. 9×9 = 81 for $k=5).
  • echo stays on the line; PHP_EOL advances — mix them carefully.
  • Validate k > 0 for interactive programs; k = 1 prints one value.
  • Bottom mirror must start at j = 2 so the center value is not duplicated.

Quick Takeaway: set k, loop $i = $k..1, print max($i,$j) for left and right halves, then break the row.

⏱️ Time and Space Complexity

ProgramTimeExtra space
Nested loops (Examples 1–2)O(k²)O(1)
printRow helper (Example 3)O(k²)O(1)
Wrap Up

🎉 Conclusion

The concentric number diamond combines top and bottom mirror loops with max($i,$j) — a natural step after concentric number squares. Master the fixed-k version first, then try user input and the printRow helper form in Example 3.

Practice the three examples above, then continue to Program 48 for the powers of 11 number pattern.

Every cell uses echo — keep PHP_EOL only after both inner column loops finish.

💡 Best Practices

✅ Do

  • Explain top half, bottom mirror, and max($i,$j) before coding
  • Use echo max($i, $j) . " " and echo PHP_EOL after both inner loops
  • Validate k ≥ 1 for interactive programs
  • Check fgets(STDIN) return value before using k
  • State O(k²) time when asked about complexity

❌ Don’t

  • Call echo PHP_EOL between left and right halves (mid-row break)
  • Start the bottom half at $i = 1 (duplicates center row)
  • Start the right half at $j = 1 (duplicates center value)
  • Hard-code 5 instead of variable k
  • Ignore bad console input in user-facing demos
  • Skip the k = 1 edge case

Key Takeaways

Knowledge Unlocked

Five things to remember about this concentric number diamond pattern

Print the pattern the beginner-friendly way.

5
Core concepts
02

Top half

i = k..1

Code
03

Bottom mirror

i = 2..k

Logic
n 04

Total rows

2*$k-1 rows

I/O
O 05

Complexity

O(k²)

Analysis

❓ Frequently Asked Questions

Top half prints 5 rows ($i=5..1) and bottom half prints 4 rows ($i=2..5). Total = 2*$k-1 = 9.
Left half $k..1 plus right half 2..$k gives $k + ($k-1) = 2*$k-1 values per row.
Starting at 2 avoids duplicating the center row ($i=1) that already printed in the top half.
Print $j when $j>$i; otherwise $i — equivalent to max($i, $j).
Program 46 prints only the top $k rows. This pattern adds a bottom mirror loop $i=2..$k for a full diamond.
Yes. Extract printRow($i, $k) and call it from both outer loops — see Example 3.
O($k²) because 2*$k-1 rows each print about 2*$k-1 values.
Use trim(fgets(STDIN)) and is_numeric($input) before casting to int.

Did you Know? 🔊

Print the top half with $i = $k..1, then mirror with $i = 2..$k. Each cell uses max($i, $j) over left $j = $k..1 and right $j = 2..$k — total rows = 2*$k-1.

Continue to Program 48

Move on to the powers of 11 number pattern in the PHP number-pattern series.

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