An inverted alphabet right-angled triangle prints the longest letter run first, then shrinks by one letter each row — still starting from A every time.
Remember
Rule: for end letter $i from last down to A,
print A through $i
ABCDE
ABCD
ABC
AB
A ← 5 rows (longest on top)
It is the flip of Program 1: keep the same inner A..$i print, reverse only the outer loop. That mirrors how star Program 2 inverts Program 1. Compare with Program 6, which shrinks from the left instead.
Approach
How to Solve It
Two ways to emit the same shape — start with nested letter loops, then optionally shorten with substr.
Method
Idea
Best for
Nested letter loops
Outer = shrinking end; inner = A..end
Learning, interviews, exams
substr($letters, 0, $i)
Slice shorter prefixes while $i counts down
Shorter demos once loops click
Pseudocode
Pseudocode
for $end from $lastLetter down to 'A':
for $ch from 'A' to $end:
echo $ch
echo PHP_EOL
Cheat sheet
Goal
Pattern
Countdown end letter
for ($i = $last; $i >= 'A'; $i--)
Print A..$i
for ($j = 'A'; $j <= $i; $j++) echo $j;
End the row
echo PHP_EOL;
Top letter from rows
$top = chr(ord('A') + $rows - 1);
One-line row shortcut
echo substr($letters, 0, $i) . PHP_EOL; while $i shrinks
1. Outer loop picks the end letter.$i runs from 'E' down to 'A' — longest row first.
2. Inner loop restarts at A. For each $i, $j runs from 'A' to $i, so the row is A..$i.
3. Print letters, then break the line.echo $j stays on the row; echo PHP_EOL after the inner loop starts the next (shorter) row.
When $i = 'E' you get ABCDE; when $i = 'A' you get A.
Example 2 — User Input Version
Read the row count at runtime. Prefer validating with is_numeric and clamp to 26 (shown in the tip below).
PHP
<?php
echo "Enter the number of rows: ";
$rows = (int) trim(fgets(STDIN));
$top = chr(ord('A') + $rows - 1);
for ($i = $top; $i >= 'A'; $i--) {
for ($j = 'A'; $j <= $i; $j++) {
echo $j;
}
echo PHP_EOL;
}
Output (when user enters 4)
Enter the number of rows: 4
ABCD
ABC
AB
A
How It Works
1. Prompt and read. Ask for a row count, then cast the trimmed line to an int.
2. Map rows to a top letter.$top = chr(ord('A') + $rows - 1) — for $rows = 4, $top is 'D'.
3. Same shrink core. Only the source of $top changes — the print logic matches Example 1.
4. Safer input tip. Prefer:
Safer input
$raw = trim(fgets(STDIN));
if (!is_numeric($raw)) {
echo "Enter a whole number from 1 to 26." . PHP_EOL;
exit;
}
$rows = (int) $raw;
if ($rows < 1 || $rows > 26) {
echo "Enter a whole number from 1 to 26." . PHP_EOL;
exit;
}
Example 3 — substr($letters, 0, $i)
Build each shrinking prefix in one call — same shape, no explicit inner letter loop.
1. Count length down.$i runs from $rows down to 1.
2. Slice the prefix.substr($letters, 0, $i) is ABCDE, then ABCD, and so on.
3. Learn loops first. Use Examples 1–2 when you need to show nested bounds; treat this as a polish shortcut afterward.
Edge Cases & Pitfalls
Check these before calling the solution done.
$i++
Growing triangle by mistake
If you increment $i from 'A' to $top, you reprint Program 1. Use $i-- from $top down to 'A'.
Stop at B
Missing final A
Stopping before 'A' drops the tip row. The condition must be $i >= 'A'.
PHP_EOL inside
Column of letters
If echo PHP_EOL is inside the inner loop, each letter lands on its own line. Use echo for letters; break the row only after the inner loop.
$rows > 26
Past Z
chr(ord('A') + $rows - 1) leaves A–Z when $rows > 26. Clamp or reject in interactive programs.
$rows = 1
Single A
Output is just A — longest and shortest coincide. A good sanity check.
Bad input
Use is_numeric
Bare (int) fgets(STDIN) turns letters into 0 — validate before the outer loop.
Analysis
Time and Space Complexity
Program
Time
Extra space
Nested loops (Examples 1–2)
O(rows²)
O(1)
substr (Example 3)
O(rows²)
O(rows) per temporary row string
Total letters = n + (n - 1) + … + 1 = n(n + 1)/2 — still quadratic in n. Same totals as Program 1.
Remember
Key Takeaways
Rule: countdown end letter $i; print A through $i each row.
Flip of Program 1: same inner loop — only reverse the outer loop.
Break the row: call echo PHP_EOL only after the inner loop.
Complexity:O(n²) time; O(1) extra space for nested loops.
One line: for $i from the top letter down to 'A', print A through $i, then echo PHP_EOL.
Frequently Asked Questions
The outer loop counts down so the first row prints the most letters and each next row prints one fewer. The inner loop still prints from A up to the current bound.
Because the inner loop always starts at A. That resets the sequence each row, producing ABCDE then ABCD and so on.
Program 1 grows row length (A, AB, ABC). This pattern shrinks it (ABCDE, ABCD, ABC). Only the outer loop direction changes; the inner loop is the same A..i print.
Program 4 grows while printing backward (A, BA, CBA). This pattern shrinks while printing forward from A (ABCDE, ABCD, ABC).
echo stays on the same line. echo PHP_EOL ends the current line. Letters use echo; the row break uses echo PHP_EOL after the inner loop.
O(n²) for n rows, because total printed characters are n(n+1)/2.
Yes. Keep a string of A–Z and print substr($letters, 0, $i) while $i counts down from $rows to 1. Nested letter loops are better for learning; substr is a handy shortcut later.
Use trim(fgets(STDIN)) and check is_numeric($input) before casting to int, then clamp rows between 1 and 26 so bad input does not walk past Z.
🤔
Did you know?
This is the inverted twin of Program 1: same inner A..$i print, only the outer loop shrinks. For 5 rows: ABCDE, ABCD, ABC, AB, A. Total letters still equal n(n+1)/2.