Shape Rule
Three conditions
Print * when $i==$j, $j==$mid, or $i==$cols+1-$j; otherwise print 0.

The star cross pattern fills a grid with 0s and prints * on the main diagonal, anti-diagonal, and middle column. This tutorial covers the three conditions, nested loops, live preview, algorithm steps, worked PHP examples, edge cases, and complexity.
Three conditions
Print * when $i==$j, $j==$mid, or $i==$cols+1-$j; otherwise print 0.
$j = 1..$cols
for ($j = 1; $j <= $cols; $j++) walks every column in the current row.
mid column
$mid = intdiv($cols, 2) + 1 locates the center column when $cols is odd (e.g. 9 → 5).
Row index i
for ($i = 1; $i <= $rows; $i++) walks each row of the rectangular grid.
1–12 rows
Pick a row count and draw the star cross pattern instantly in the browser (columns fixed at 9).
Complexity
Visits every cell once — $rows×$cols iterations; extra memory stays O(1).
A star cross pattern with 0s prints * on the main diagonal, anti-diagonal, and middle column; every other cell prints 0. With $rows = 4 and $cols = 9, the last row becomes 000***000.
In PHP you use nested loops ($i = 1..$rows, $j = 1..$cols) and a three-part if that picks * or 0 for each cell.
It combines diagonal math with a center-column check — a classic grid pattern after number diamonds.
$i == $j draws the top-left to bottom-right line.
$i == $cols + 1 - $j completes the X shape.
$j == $mid adds the vertical line through the center.
Follow Program 44 number diamond; continue to Program 46 concentric square.
In short: nested row/column loops, three-part if for *, else 0; call echo PHP_EOL after each row.
Given $rows = 4 and $cols = 9, print a grid where * marks the X and middle column; all other cells are 0.
// $rows = 4, $cols = 9 (conceptual shape)
// *000*000*
// 0*00*00*0
// 00*0*0*00
// 000***000 | Item | Type | Description |
|---|---|---|
$rows | int | Number of rows in the grid (typically ≥ 1). |
$cols | int | Number of columns (9 in the classic example; odd width gives one center column). |
| Printed output | text | rows × cols characters — * on cross lines, 0 elsewhere. |
$mid = intdiv($cols, 2) + 1
for $i from 1 to $rows:
for $j from 1 to $cols:
if $i==$j or $j==$mid or $i==$cols+1-$j: print *
else: print 0
print newline | Approach | Idea | Best for |
|---|---|---|
| Three-condition grid | *000*000* first row with X + mid column | Learning and interviews |
| User-input rows | trim(fgets(STDIN)) with fixed $cols = 9 | Flexible console programs |
| X-only cross | Drop $j == $mid — diagonals only | Contrast with full cross |
| Goal | Pattern |
|---|---|
| Walk rows | for ($i = 1; $i <= $rows; $i++) |
| Walk columns | for ($j = 1; $j <= $cols; $j++) |
| Cross if | $i==$j || $j==$mid || $i==$cols+1-$j |
| Center column | $mid = intdiv($cols, 2) + 1 |
| End the row | echo PHP_EOL; |
| Program 44 contrast | Number diamond uses mirrored rows; this pattern uses a fixed grid with diagonal checks |
Same grid cell — how the three cross conditions pick * or 0.
$i == $jMain diagonal — top-left to bottom-right
i == $cols+1-$jSecondary diagonal for the X shape
$j == $midVertical line through center ($mid = intdiv($cols, 2)+1)
trace i=2,j=5Dry-run cell (2,5): mid column → prints *
Reach for this pattern when teaching diagonal conditions inside a full row×column grid.
Classic follow-up after diamonds and symbol grids.
Outer/inner bound practice with an immediate visual check.
Combine loops with fgets(STDIN) for a flexible row count.
Compare with Program 44 (number diamond), then continue to Program 46 (concentric square).
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($rows×$cols) thinking.
Choose a row count (columns fixed at 9) and draw the star cross pattern in the browser.
Three complete PHP programs — fixed row count, fgets(STDIN) input, and an X-only cross variant. Click View Output to reveal sample console results.
Print four rows over nine columns with nested loops and a three-part if.
$rows = 4, $cols = 9Hard-coded size — nested loops and the cross check build each row.
<?php
$rows = 4;
$cols = 9;
$mid = intdiv($cols, 2) + 1;
for ($i = 1; $i <= $rows; $i++) {
for ($j = 1; $j <= $cols; $j++) {
if ($i == $j || $j == $mid || $i == $cols + 1 - $j) {
echo "*";
} else {
echo "0";
}
}
echo PHP_EOL;
} When $i = 1, $j = 1, the main-diagonal check prints *. When $i = 2, $j = 5, the middle-column check prints * while neighbors print 0.
Let the user choose the row count at runtime (columns stay at 9).
Read the row count with trim(fgets(STDIN)) (check is_numeric($input) in real apps).
<?php
echo "Enter the number of rows: ";
$input = trim(fgets(STDIN));
if (!is_numeric($input)) {
echo "Invalid input." . PHP_EOL;
exit(1);
}
$rows = (int) $input;
$cols = 9;
$mid = intdiv($cols, 2) + 1;
for ($i = 1; $i <= $rows; $i++) {
for ($j = 1; $j <= $cols; $j++) {
if ($i == $j || $j == $mid || $i == $cols + 1 - $j) {
echo "*";
} else {
echo "0";
}
}
echo PHP_EOL;
} Same nested-loop core as Example 1; only the source of $rows changes. Non-numeric input fails is_numeric($input) — validate before casting to int for safer labs.
Remove the middle-column check for a plain X without the vertical center line.
Remove the middle-column check to print a plain X without the vertical center line.
<?php
$rows = 4;
$cols = 9;
for ($i = 1; $i <= $rows; $i++) {
for ($j = 1; $j <= $cols; $j++) {
if ($i == $j || $i == $cols + 1 - $j) {
echo "*";
} else {
echo "0";
}
}
echo PHP_EOL;
} Same nested-loop grid; dropping $j == $mid leaves only the two diagonals that form the X.
echo is built in; use fgets(STDIN) when reading input. Set $rows, $cols = 9, and $mid = intdiv($cols, 2) + 1.
for ($i = 1; $i <= $rows; $i++) — walks each row of the grid.
for ($j = 1; $j <= $cols; $j++) visits every column in the current row.
Three checks print *; else 0, then echo PHP_EOL ends the row.
Total cell visits equal $rows×$cols — O($rows×$cols) time, O(1) extra memory.
$i = 2, $j = 5Trace one center-column cell to see the three checks in action.
| Check | Result | Prints |
|---|---|---|
$i == $j (2==5) | false | — |
$j == $mid (5==5) | true | * |
i == $cols+1-$j (2==5) | false | — |
Cell output: * — full grid visits: 4×9 = 36 = $rows×$cols.
Where this tiny pattern (and its loop structure) shows up beyond the homework prompt.
Clearest visual proof that outer and inner bounds interact.
Example: drop $j == $mid and get an X-only cross instead.
Foundation for symbol grids, diagonal patterns, and cross variants.
Example: swap * and 0 for 1 and 0 to build a number cross.
Practice echo vs row newline without complex math.
Example: put echo PHP_EOL inside the inner loop by mistake.
Swap * and 0 for other symbols once the loop works.
Example: replace * with 1 and keep 0 as fill.
Grid totals make O($rows×$cols) concrete for beginners.
Example: count cells for rows=4, cols=9 → 36 visits.
Pair the pattern with fgets(STDIN) and positive-row checks.
Example: reject rows <= 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.
Why this pattern earns a permanent spot in beginner PHP courses.
Wrong diagonal formulas show up immediately as a broken or shifted X.
Only loops and console output — no arrays or math libraries.
Drop the middle column, swap symbols, or change column width with small edits.
Streaming output needs no storage beyond loop counters.
Pro Tip: learn the three-condition grid first; then try the X-only cross in Example 3.
Small habits that keep number-pattern code clean.
Use $rows (or n) and keep i/j for row/column — or rename to row/col.
fgets(STDIN)Avoid crashes when the user types letters instead of a number.
Only call echo PHP_EOL after the inner loop finishes the row.
Compact if: echo ($i==$j||$j==$mid||$i==$cols+1-$j ? "*" : "0"); inside the inner loop.
Trace $rows = 3 on paper before coding larger demos.
Pro Tip: if the output is a vertical list of characters per line, you almost certainly put echo PHP_EOL inside the inner loop.
Mistakes that commonly break star cross patterns.
Each character lands on its own line — you get a column, not a grid row.
→ Use echo for each cell; echo PHP_EOL only after the inner loop finishes.
Using i + j == cols instead of $i == $cols + 1 - $j shifts the secondary diagonal.
→ Keep $i == $cols + 1 - $j for cols=9 (e.g. row 2, col 8 → 2==2).
Omitting echo PHP_EOL glues every row onto one endless line.
→ Always end the row after the inner loop.
Letters or empty input leave $rows unset.
→ Use is_numeric($input) and re-prompt on failure.
Computing $mid after the loops or using even $cols without adjusting center logic.
→ Set $mid = intdiv($cols, 2) + 1 once before the loops; prefer odd column counts.
Check these inputs before calling the solution done.
Output is one row of nine characters following the same three checks.
Outer loop never runs — print nothing or show a message.
rows < 0Treat as invalid; re-prompt instead of silent empty output.
Output grows as $rows*$cols cell visits plus spaces — fine for labs, noisy for huge n.
Unchecked fgets(STDIN) leaves $rows unset — call is_numeric($input) first.
Remove $j == $mid for a plain X — see Example 3.
Try these variations to lock in the pattern.
$cols = 7 or $cols = 11 and observe $mid* with 1 and keep 0 as fill$j == $mid like Example 3$rows×$cols (e.g. 4×9 = 36).echo stays on the line; echo PHP_EOL advances — mix them carefully.$rows > 0 for interactive programs; $rows = 1 prints one cross row.$cols so $mid points to one clear center column; even widths split the center.Quick Takeaway: compute $mid, loop rows and columns, three-part if for *, else 0, then break the row.
| Program | Time | Extra space |
|---|---|---|
| Nested loops (Examples 1–2) | O($rows×$cols) | O(1) |
| X-only cross (Example 3) | O($rows×$cols) | O(1) |
The star cross pattern with 0s combines nested loops with a simple grid fill pattern — a natural step after number diamonds. Master the fixed-$rows version first, then try user input and the X-only cross in Example 3.
Practice the three examples above, then continue to Program 46 for the concentric number square pattern.
Every cell uses print — keep echo PHP_EOL only after the inner column loop finishes.
print("*") or print("0") and echo PHP_EOL after each row$rows ≥ 1 for interactive programsfgets(STDIN) return value before using $rowsecho PHP_EOL inside the inner column loop$mid = intdiv($cols, 2) + 1 before the loopsi + j == cols instead of $i == $cols + 1 - $j$rows = 1 edge casePrint the pattern the beginner-friendly way.
Each cell picks * or 0
DefinitionThree-part if
Code$i==$cols+1-$j
Logic$rows×$cols
I/OO($rows×$cols)
AnalysisA * prints on the main diagonal ($i==$j), anti-diagonal ($i==$cols+1-$j), and middle column ($j==$mid). Every other cell prints 0.
Move on to the concentric number square pattern in the PHP number-pattern series.
12 people found this page helpful