A left-shifted descending number triangle starts each row at $i and prints through $rows, so the left edge moves right as the row shortens.
Remember
Rule: for i = 1..n, print j = i..n
12345
2345
345
45
5 ← 5 rows
In PHP the outer loop picks the row start $i, the inner loop prints $j from $i to $rows with echo $j, then echo PHP_EOL ends the row. Program 1 is the twin that shrinks from the right (12345, 1234, 123…).
Approach
How to Solve It
Outer loop from 1 to $rows. Inner loop from current $i to $rows. End each row with echo PHP_EOL.
Method
Idea
Best for
Nested loops
Outer picks start $i; inner prints $i..$rows
Learning, interviews, exams
String concat
Build each row, then echo once
Leaner demos once loops click
Pseudocode
Pseudocode
for i from 1 to rows:
for j from i to rows:
print j (no newline)
print newline
Cheat sheet
Goal
Pattern
Pick row start
for ($i = 1; $i <= $rows; $i++)
Print $i..$rows
for ($j = $i; $j <= $rows; $j++) echo $j;
End the row
echo PHP_EOL;
String form
$row .= $j; then echo $row . PHP_EOL;
Program 1 twin
for ($i = $rows; $i >= 1; $i--) with $j = 1..$i
Printing Numbers vs Starting a New Line
API
Effect
Use for
echo $j
Stays on the same line
Each digit in the run
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 left-shifted triangle updates instantly — capped at 9 so every digit stays a single character.
Whole numbers from 1 to 9 (single digits). Tap a chip or type a value — the preview redraws as you go.
Live result5 rows · 15 digits
12345
2345
345
45
5
Trace
Worked Walkthrough
Trace $rows = 4 — each outer-loop value of $i, the inner range, and the printed row.
$i
Inner $j
Length
Printed row
1
1..4
4
1234
2
2..4
3
234
3
3..4
2
34
4
4..4
1
4
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 string-concatenation shortcut. Use View Output for sample results.
Example 1 — Fixed $rows = 5
Outer loop picks start $i; inner loop prints $i..$rows.
1. Same bounds. Outer and inner ranges match Example 1.
2. Append, then echo.$row .= $j builds the line; echo $row . PHP_EOL prints it once.
3. Same shape. Identical output to Example 1 — keep the nested-loop version for exams that expect two loops.
Edge Cases & Pitfalls
Check these before calling the solution done.
wrong twin
for ($j = 1; $j <= $i; $j++)
That reprints Program 1 / Program 5 shapes. Keep the inner start at $i for this left-shift.
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.
rows = 1
Single digit
Output is just 1 — a good sanity check.
rows ≤ 0
Empty output
The outer loop never runs. Validate and prompt again for clearer UX.
multi-digit
$rows > 9
echo 10 prints two characters. Labs usually stick to 1–9 for a clean single-digit look.
spaces
Do not add spaces between digits
The classic sample is concatenated (2345), not spaced (2 3 4 5).
Analysis
Time and Space Complexity
Program
Time
Extra space
Nested loops (Examples 1–2)
O(n²)
O(1)
String concatenation (Example 3)
O(n²)
O(1) beyond the row string
There are n rows printing n+(n-1)+…+1 digits, so total work is n(n+1)/2.
Remember
Key Takeaways
Rule: for each $i from 1 to $rows, print digits $i..$rows.
Inner start:$j = $i is what shifts the left edge right each row.
echo vs PHP_EOL: digits stay on the line; echo PHP_EOL advances after each row.
Next step: Program 3 reverses the digit order on each shrinking row.
One line: for each start $i, print $i..$rows with echo $j, then echo PHP_EOL.
Frequently Asked Questions
The inner loop starts at $j = $i, not $j = 1. When $i increases (1, 2, 3, ...), each row begins at that value and prints until $rows.
Because each next row starts at a higher $i, numbers below $i are not printed anymore — the triangle shifts left visually.
echo $j stays on the same line. echo PHP_EOL ends the current line. Digits use echo; the row break uses echo PHP_EOL after the inner loop.
Program 1 counts the outer loop down and prints 1..$i (12345, 1234, 123…). Program 2 counts up and prints $i..$rows (12345, 2345, 345…) — same total prints, different shape.
Yes. Append each digit to a string with $row .= $j, then echo the row with PHP_EOL — same shape with a different output style.
O(n²) for n rows because total prints are n+(n-1)+…+1 = n(n+1)/2.
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?
Each row starts at $i and prints through $rows, so the left edge shifts right each line — still O(n²) total prints for n rows.