A descending number triangle prints digits 1..i on each row, with the outer loop counting down so the first row is longest.
Remember
Rule: for i = n..1, print 1..i
12345
1234
123
12
1 ← 5 rows
In PHP you solve it with two nested for loops: the outer loop picks the row length, the inner loop prints digits with echo $j, then echo PHP_EOL ends the row. Flip the outer loop upward for an ascending triangle (Program 5).
Approach
How to Solve It
Outer loop counts down from $rows to 1. Inner loop prints digits 1..i. End each row with echo PHP_EOL.
Method
Idea
Best for
Nested loops
Outer = length n..1, inner = digits 1..i via echo
Learning, interviews, exams
Spaced digits
echo $j . " " instead of echo $j
Easier reading on each row
Pseudocode
Pseudocode
for i from rows down to 1:
for j from 1 to i:
print j (no newline)
print newline
Cheat sheet
Goal
Pattern
Shrink each row
for ($i = $rows; $i >= 1; $i--)
Print digits 1..i
for ($j = 1; $j <= $i; $j++) echo $j;
End the row
echo PHP_EOL;
Spaced form
echo $j . " ";
Ascending instead
for ($i = 1; $i <= $rows; $i++) with the same inner loop
Printing Numbers vs Starting a New Line
API
Effect
Use for
echo $j
Stays on the same line
Each digit $j
echo PHP_EOL
Ends the current line
After the inner loop
Print all digits without a newline, then end the row once.
Try it
Live Preview
Change the row count and the descending triangle updates instantly — capped at 9 so every digit stays a single character.
Whole numbers from 1 to 9. Tap a chip or type a value — the preview redraws as you go.
Live result5 rows · 15 digits
12345
1234
123
12
1
Trace
Worked Walkthrough
Trace $rows = 4 — each outer-loop value of $i and the digits the inner loop prints.
$i
Inner $j
Printed row
Digits
4
1..4
1234
4
3
1..3
123
3
2
1..2
12
2
1
1..1
1
1
Total digits are 4+3+2+1 = 10 — the triangular number n(n+1)/2.
Code
PHP Programs
Three complete programs: fixed height, CLI input, and a spaced-digit variant. Use View Output for sample results.
Example 1 — Fixed $rows = 5
Outer loop shrinks the length; inner loop prints digits 1..i.
1. Same structure. Only the print expression changes — loops stay identical to Example 1.
2. Space after each digit.echo $j . " " separates values for clearer scanning.
3. When to use it. Prefer the tight form for classic screenshots; use spaced form when teaching or tracing by hand.
Edge Cases & Pitfalls
Check these before calling the solution done.
grow not shrink
for ($i = 1; $i <= $rows; $i++)
That outer loop grows the triangle (1, 12, 123…). Keep $i = $rows; $i >= 1; $i-- for this pattern.
PHP_EOL inside
echo PHP_EOL inside the inner loop
That puts each digit on its own line. Print digits without a newline; call echo PHP_EOL only after the row finishes.
off-by-one
$j < $i instead of $j <= $i
You drop the last digit on every row (e.g. 1234 becomes 123).
rows = 1
Single 1
Output is just 1 — a good sanity check.
rows ≤ 0
Empty output
The outer loop never runs. Validate and prompt again for clearer UX.
fgets
Check is_numeric
Bare (int) casts turn non-numeric strings into 0 — prefer is_numeric before casting.
Analysis
Time and Space Complexity
Program
Time
Extra space
Fixed / input (Examples 1–2)
O(n²)
O(1)
Spaced digits (Example 3)
O(n²)
O(1)
There are n rows printing n+(n-1)+…+1 digits, so total work is n(n+1)/2.
Remember
Key Takeaways
Rule: for $i = n..1, print digits 1..i with echo.
Count down: the outer loop starts at $rows so the first line is longest.
echo vs PHP_EOL: digits stay on the line; echo PHP_EOL advances after each row.
Next step: Program 2 shifts the start digit left each row.
One line: for each length from n down to 1, print 1..i with echo, then echo PHP_EOL.
Frequently Asked Questions
The outer loop runs i from rows down to 1. For each row i, the inner loop runs j from 1 to i and prints j with echo. Row rows prints 1..rows, the next row prints one fewer digit, down to a single 1.
Counting down makes the first row the longest. for ($i = $rows; $i >= 1; $i--) sets i to the full width first, then shrinks by one each line — matching 12345, 1234, 123, 12, 1.
echo $j sends output without adding a line break. echo PHP_EOL ends the current line with a portable newline. Digits use echo; the row break uses echo PHP_EOL after the inner loop.
Change the outer loop to for ($i = 1; $i <= $rows; $i++). Keep the inner loop as for ($j = 1; $j <= $i; $j++) echo $j. The first row then has one digit and the last row has rows digits — that is Program 5.
O(n²) where n is the number of rows. Total echo calls equal 1+2+…+n = n(n+1)/2.
Yes. echo chr(ord('0') + $j) writes one digit when j is 1..9. Nested loops with chr output are a common shortcut; keep echo $j if your course examples use it.
Use trim(fgets(STDIN)) and check is_numeric($input) before casting to int so bad input does not produce unexpected results.
The outer loop never runs, so nothing is printed. Validate and prompt again if you want a clear user message.
🤔
Did you know?
Row i prints digits 1 through i. The outer loop counts down from rows, so the first line is longest and each row shortens by one digit — still O(n²) total prints. This is the classic first console pattern in PHP labs.