1. Outer loop picks the letter.$i runs from 'A' to 'E' — that letter fills the whole row.
2. Inner loop sets the width.$j runs from 'E' down to $i, so widths are 5, 4, 3, 2, 1.
3. Print $i, not $j.echo $i keeps the row uniform (AAAAA, not EDCBA).
4. Break the line.echo PHP_EOL after the inner loop starts the next row.
Example 2 — User Input Version
Read the height at runtime. Prefer validating with is_numeric and clamp to 1–26 (shown in the tip below).
PHP
<?php
echo "Enter the number of rows: ";
$rows = (int) trim(fgets(STDIN));
for ($row = 0; $row < $rows; $row++) {
$ch = chr(ord('A') + $row);
$repeat = $rows - $row;
for ($k = 1; $k <= $repeat; $k++) {
echo $ch;
}
echo PHP_EOL;
}
Output (when user enters 4)
Enter the number of rows: 4
AAAA
BBB
CC
D
How It Works
1. Prompt and read. Ask for a row count, then cast the trimmed line to an int.
2. Index form of the same shape. Row 0 prints A$rows times; row 1 prints B$rows - 1 times; and so on.
3. 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 — str_repeat($ch, $repeat)
Build each repeated-letter row in one call — same shape, no explicit inner print loop.
1. One outer loop. Still walk $row from 0 to $rows - 1.
2. Build the row.str_repeat($ch, $repeat) creates a string of length $repeat filled with $ch.
3. Print and advance. Append PHP_EOL so each row ends on its own line.
Learn the two-loop version first (Examples 1–2) so you can explain both bounds; treat this as a polish shortcut afterward.
Edge Cases & Pitfalls
Check these before calling the solution done.
echo $j
Stepping letters
If you print $j instead of $i, the first row becomes EDCBA. Always echo $i for this shape.
Countdown outer
Program 11 by mistake
Counting $i from top down to A prints EEEEE first. Outer loop must advance A→top.
PHP_EOL inside
Column of letters
If echo PHP_EOL sits inside the inner loop, each letter lands on its own line. Call it only after the inner loop.
$rows > 26
Past Z
Clamp to 1–26 so chr(ord('A') + $row) never walks past Z.
$rows = 1
Single A
Output is just A — 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)
str_repeat (Example 3)
O(rows²)
O(rows) per temporary row string
Total letters printed = n + (n - 1) + … + 1 = n(n + 1)/2, which is still quadratic in n.
Remember
Key Takeaways
Rule: letters advance A→top; widths shrink n..1.
Print $i: the outer letter fills the row; $j only sets the count.
Break the row:echo for letters; echo PHP_EOL after the inner loop.
Complexity:O(n²) time; O(1) extra space for nested loops.
One line: for each letter $i from A to top, print $i(ord($top) - ord($i) + 1) times, then echo PHP_EOL.
Frequently Asked Questions
Program 11 prints EEEEE, DDDD, ... (letters step down). Program 12 prints AAAAA, BBBB, ... (letters step up) with the same inverted widths 5..1.
When $i is A, the inner loop runs from E down to A (5 times) and prints A each time. Next $i becomes B, the inner loop runs 4 times (E..B) and prints B.
$j only controls how many times the loop runs. Printing $i keeps the entire row the same letter; printing $j would step letters across the row.
Because the inner loop runs from the fixed top letter down to the current $i. As $i increases, the loop has fewer iterations.
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²) where n is the number of rows. Total echo calls equal n+(n-1)+…+1 = n(n+1)/2.
Yes. echo str_repeat($ch, $repeat) . PHP_EOL prints a full repeated-letter row in one call. Nested loops are better for learning; str_repeat 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 forward-letter twin of Program 11: same inverted widths (5…1), but letters advance A→E instead of stepping down. Print the outer loop letter inside the inner loop so each row stays uniform.