Shape Rule
Pyramid + mirror
Grow to 2*rows-1 stars, then shrink back to 1 - solid stars every row.

A filled diamond is a center-aligned pyramid stacked with its mirror: spaces for centering, odd star counts for symmetry, and a lower half that starts at rows - 1. This tutorial covers the shape rule, both halves, a live preview, algorithm steps, worked JavaScript examples, edge cases, and complexity.
Pyramid + mirror
Grow to 2*rows-1 stars, then shrink back to 1 - solid stars every row.
rows - i
Center each row with rows - i spaces before the stars.
2*i - 1
Print 1, 3, 5, … stars so every row has a single center.
Start at rows - 1
Lower half begins below rows so the widest line prints once.
1–12 rows
Pick a half-height and draw the solid diamond in the browser.
Complexity
2n - 1 lines, each Θ(n) work - overall O(n²), O(1) extra space.
A filled diamond is a solid, center-aligned diamond of * characters. You build it by appending a centered pyramid for i = 1…rows, then the same row formula with i running from rows - 1 down to 1.
Unlike the hollow diamond (Program 9), every position in the star segment is filled. Tip rows are shorter; the middle row has 2 * rows - 1 stars and no leading spaces when i == rows.
It stitches two earlier skills - Program 5’s pyramid and reverse outer iteration - into one figure. Once this clicks, hollow and framed diamonds are smaller jumps.
Upper 1..rows, then lower rows-1..1.
Spaces then odd star runs - reused in both halves.
2*i - 1 keeps a centered peak each row.
Full star segments - not an outline like Program 9.
In short: for each half, append rows - i spaces and 2 * i - 1 stars; grow i to rows, then shrink from rows - 1 to 1.
Given a positive integer rows (half-height of the diamond), print a solid center-aligned diamond with 2 * rows - 1 lines.
# rows = 5 (conceptual shape; spaces shown as ·)
# ····*
# ···***
# ··*****
# ·*******
# *********
# ·*******
# ··*****
# ···***
# ····* | Item | Type | Description |
|---|---|---|
rows | int | Half-height (number of rows in the upper pyramid, typically ≥ 1). |
| Printed output | text | 2 * rows - 1 centered lines; row formula uses spaces + odd star runs. |
for i from 1 to rows: // upper half
append (rows - i) spaces
append (2 * i - 1) stars
console.log(line)
for i from rows - 1 down to 1: // lower half
append (rows - i) spaces
append (2 * i - 1) stars
console.log(line) | Approach | Idea | Best for |
|---|---|---|
| Two outer loops | Upper grow + lower shrink, shared inners | Learning and interviews |
printRow helper | Build spaces and stars as strings | Shorter demos after loops click |
| Goal | Pattern |
|---|---|
| Leading spaces | for (let s = 1; s <= rows - i; s++) line += " " |
| Star run | for (let j = 1; j <= 2 * i - 1; j++) line += "*" |
| Upper half | for (let i = 1; i <= rows; i++) |
| Lower half | for (let i = rows - 1; i >= 1; i--) |
| Total lines | 2 * rows - 1 |
| Widest stars | 2 * rows - 1 (when i == rows) |
Same family of patterns - different fill and loop range.
solid diamondFull 2*i-1 star runs; tip rows shorter
hollow outlineDiagonal stars only; fixed width 2*rows-1
upper onlySame inners as this page’s first half
say both halvesExplain grow then shrink - and why skip i == rows twice
Reach for a filled diamond when combining centering with a grow-then-shrink outer sequence.
Natural next step once Program 5’s centered triangle is solid.
Practice ascending then descending outer bounds with shared inners.
Odd star counts and matching space formulas teach left–right balance.
Programs 9 and 11 reuse the two-phase idea with different fill rules.
Terminal teaching pattern - not how you draw diamonds in UI frameworks.
Key benefit: one figure that combines centering, odd widths, and careful outer-loop sequencing without duplicate middle rows.
Choose a half-height between 1 and 12 and draw the filled diamond in the browser.
Three complete JavaScript programs - fixed half-height, prompt input, and a printRow helper with repeat. Click View Output to reveal sample console results, or Try it Yourself to run in the browser editor.
Print a diamond with half-height 5 using classic nested loops.
rows = 5Same space / star inner loops as Program 5, plus the mirrored lower half.
let rows = 5;
// Upper half
for (let i = 1; i <= rows; i++) {
let line = "";
for (let s = 1; s <= rows - i; s++) {
line += " ";
}
for (let j = 1; j <= 2 * i - 1; j++) {
line += "*";
}
console.log(line);
}
// Lower half (no duplicate widest row)
for (let i = rows - 1; i >= 1; i--) {
let line = "";
for (let s = 1; s <= rows - i; s++) {
line += " ";
}
for (let j = 1; j <= 2 * i - 1; j++) {
line += "*";
}
console.log(line);
} Upper i grows from 1 to 5: spaces shrink, stars grow 1, 3, 5, 7, 9. Lower i shrinks from 4 to 1: spaces grow, stars shrink 7, 5, 3, 1 - closing the diamond without reprinting the middle row.
Let the user choose the half-height at runtime.
Read rows with prompt and parseInt (validate with Number.isFinite in real apps).
let rows = parseInt(prompt("Enter the number of rows:"), 10);
if (!Number.isFinite(rows) || rows < 1) {
console.log("Please enter a whole number of rows >= 1.");
} else {
for (let i = 1; i <= rows; i++) {
let line = "";
for (let s = 1; s <= rows - i; s++) {
line += " ";
}
for (let j = 1; j <= 2 * i - 1; j++) {
line += "*";
}
console.log(line);
}
for (let i = rows - 1; i >= 1; i--) {
let line = "";
for (let s = 1; s <= rows - i; s++) {
line += " ";
}
for (let j = 1; j <= 2 * i - 1; j++) {
line += "*";
}
console.log(line);
}
} Same two-phase core as Example 1; only the source of rows changes. Non-numeric input yields NaN with bare parseInt(prompt(), 10) - validate with Number.isFinite for safer labs.
Same diamond without explicit inner character loops.
printRow Helper + repeatBuild each row’s margin and star run in one call each.
function printRow(rows, i) {
console.log(" ".repeat(rows - i) + "*".repeat(2 * i - 1));
}
let rows = 5;
for (let i = 1; i <= rows; i++) {
printRow(rows, i);
}
for (let i = rows - 1; i >= 1; i--) {
printRow(rows, i);
} printRow encodes the shared formula once; both outer loops call it. Great after you understand the nested-loop version - keep the explicit space/star loops for exams that want both bounds visible.
i = 1 … rows)Print rows - i spaces, then 2 * i - 1 stars, then a newline. Star counts: 1, 3, 5, …, 2*rows-1.
i = rows - 1 … 1)Reuse the same two inner loops. As i shrinks, spaces grow and stars shrink - for rows = 5: 7, 5, 3, 1.
2 * i - 1?Odd widths keep a single center star. Growing by two stars per step adds one on each side and preserves symmetry.
console.log(line) after the star loop ends each diamond line in both phases.
2 * rows - 1 lines; widest line has 2 * rows - 1 stars. O(n²) for n = rows, O(1) extra space.
rows = 4Trace each outer-loop i: spaces, stars, and which half produced the line.
| Half | i | Spaces rows - i | Stars 2*i - 1 | Printed row |
|---|---|---|---|---|
| Upper | 1 | 3 | 1 | * |
| Upper | 2 | 2 | 3 | *** |
| Upper | 3 | 1 | 5 | ***** |
| Upper | 4 | 0 | 7 | ******* |
| Lower | 3 | 1 | 5 | ***** |
| Lower | 2 | 2 | 3 | *** |
| Lower | 1 | 3 | 1 | * |
Total lines: 2 × 4 - 1 = 7. The widest row (i = 4) appears only in the upper half.
Where this diamond (and its two-phase loop structure) shows up beyond the homework prompt.
Prove you can reuse Program 5’s row body in a second phase.
Example: extract a printRow(rows, i) helper.
Odd widths and matching margins train left–right balance.
Example: swap to i stars and watch centering break.
Starting lower at rows duplicates the peak - a classic bug.
Example: set lower start to rows and compare output.
Swap * for digits or letters once the geometry works.
Example: print i inside the star run for a number diamond.
Solid fill vs outline (Program 9) clarifies why inner logic differs.
Example: side-by-side outputs for the same rows.
2n-1 lines of Θ(n) work make O(n²) concrete.
Example: count printed characters for n = 5.
Pro Tip: in interviews, say “upper pyramid, then mirror from rows-1” before writing loops - that sequence is the whole design.
Why this solid-diamond approach is a favorite teaching pattern.
Same space/star formulas as Program 5 - only the outer sequence changes.
Odd star counts make centering errors obvious immediately.
One printRow helper serves both outer loops cleanly.
Streaming console output needs only loop counters.
Pro Tip: master the nested-loop version first; treat printRow as a polish shortcut afterward.
Small habits that keep filled-diamond code clean.
Spaces + stars + newline belong in one place so both halves stay identical.
rows - 1Never start the mirror at rows unless you want a doubled middle line.
2 * i - 1Using i stars alone breaks centered diamond symmetry.
parseInt(prompt(), 10) with Number.isFiniteAvoid NaN rows when reading interactive row counts.
Trace rows = 3 or 4 on paper before coding larger demos.
Pro Tip: if the middle row appears twice, your lower loop almost certainly started at i = rows.
Mistakes that commonly break filled diamond patterns.
rowsThe widest line prints twice and the diamond looks “fat” in the middle.
→ Start the second outer loop at rows - 1.
i Stars Instead of 2*i - 1You get a left-leaning or uneven shape, not a centered diamond.
→ Keep odd star counts: 2 * i - 1.
Hollow diamonds need different inner logic and fixed line width - not a one-line tweak.
→ Use Program 9 for outlines.
rows - i + 1 or i spaces shifts the whole figure off-center.
→ Leading spaces are exactly rows - i.
Letters or empty input yield NaN.
→ Check Number.isFinite and require rows >= 1.
Check these inputs before calling the solution done.
Upper prints *; lower loop does not run - output is one line.
Both halves skip - print nothing or show a validation message.
rows < 0Treat as invalid; re-prompt instead of silent empty output.
Middle width is 2*n-1 stars - fine for labs; wrap or scroll on tiny terminals.
parseInt(prompt(), 10) yields NaN - validate first.
rows meaningConfirm whether the prompt means half-height or total lines (2n-1).
Try these variations to lock in the pattern.
rows >= 1* with digits or i2 * rows - 1; widest stars are also 2 * rows - 1.(rows - i) + (2*i - 1) = rows + i - 1 - tip rows are shorter than the middle.rows > 0 for interactive programs; rows = 1 should print a single star.Quick Takeaway: spaces = rows - i, stars = 2*i - 1, grow then shrink from rows - 1 - that is the filled diamond.
| Program | Time | Extra space |
|---|---|---|
| Nested loops (Examples 1–2) | O(rows²) | O(1) |
printRow helper (Example 3) | O(rows²) | O(rows) temporary per row string |
About 2 * rows - 1 lines; each line does Θ(rows) work for spaces and stars combined.
The filled diamond is a centered pyramid plus its mirror: shared rows - i spaces and 2 * i - 1 stars, with the lower half starting at rows - 1 so the peak prints once. Master that two-phase story and hollow or framed diamonds become incremental changes.
Practice the three examples above, then continue to the diamond-in-square pattern for a framed follow-up.
Grow to rows, shrink from rows - 1, keep odd star runs - and validate half-height when reading input.
rows - i spaces and 2 * i - 1 starsrows - 1Number.isFinite for interactive demosi == rowsi stars when you need a centered diamondrows = 1 edge casePrint the solid diamond the beginner-friendly way.
Grow then shrink
Structurerows - i
Formula2*i - 1
FormulaLower from rows-1
GotchaO(n²) time
AnalysisThe filled diamond is Program 5’s pyramid plus its mirror: same (rows - i) spaces and (2 * i - 1) stars, with the lower half starting at rows - 1 so the widest row prints only once.
Frame a hollow diamond inside solid top and bottom rows for Program 11.
12 people found this page helpful