Problem overview
The function printRhombus receives an odd positive integer n and prints a rhombus of stars on n lines, each exactly n characters wide. For n = 5:
*
***
*****
***
*
Each line has spaces on both sides, including the right side. The first line is two spaces, one star and two spaces. The statement stresses those trailing spaces, so they must be printed.
Approach
Every line is described by two numbers: how many stars it has, and how many spaces sit on each side of them. Because the shape is symmetric, the left and right counts are equal, so one variable covers both. The line is then spaces spaces, stars stars and spaces spaces again.
The counts follow a pattern. The first line has 1 star and n / 2 spaces per side. Down to the middle line, each line gains 2 stars and loses 1 space per side. Past the middle, each line loses 2 stars and gains 1 space per side. For n = 5 the stars go 1, 3, 5, 3, 1 and the spaces go 2, 1, 0, 1, 2. In every line, stars + 2 * spaces equals n, which is why each line has the right width.
Building a line out of repeated characters is a job of its own, so the lesson puts it in a helper, buildString, and calls it three times per line.
A quick check of the width rule on the middle line: it has 5 stars and 0 spaces, and 5 + 2 * 0 = 5. On the second line there are 3 stars and 1 space per side, and 3 + 2 * 1 = 5 again. If the counters ever break this equation, the shape is wrong, which makes it a good sanity check while you debug.
Step by step
- Declare
starsas 1 andspacesasn / 2. With integers,5 / 2is 2, and for oddnthis is exactly the number of spaces needed. - Loop
ifrom 0 whilei < n: one pass per line. - In the loop, join the spaces, stars and spaces, each from
buildString, intostrand print it withfmt.Println. A line ending in+continues on the next line. - Update the counters for the next line. If
i < n / 2the shape is still widening, so add 2 tostarsand subtract 1 fromspaces. Otherwise subtract 2 fromstarsand add 1 tospaces. - Write
buildString(n int, character string) stringbelowprintRhombus. It starts from an empty string, loopsntimes appendingcharacter, and returns the result.
The middle line has i == n / 2. It goes to the else branch, so the update after the middle line already starts narrowing. That is the point: the middle line has been printed with the maximal width, and the next one must be smaller.
The solution in Go
func printRhombus(n int) {
stars := 1
spaces := n / 2
for i := 0; i < n; i++ {
str := buildString(spaces, " ") +
buildString(stars, "*") +
buildString(spaces, " ")
fmt.Println(str)
if i < n / 2 {
stars += 2
spaces -= 1
} else {
stars -= 2
spaces += 1
}
}
}
func buildString(n int, character string) string {
str := ""
for i := 0; i < n; i++ {
str += character
}
return str
}
Language details worth knowing
Go ends a statement at a line break, so a long expression can only continue on the next line if the line ends with an operator. That is why the two + signs are at the ends of the lines, not at the start of the next ones. Moving the + to the next line is a syntax error.
The helper takes the character as a string, such as " " or "*", not as a rune. Strings concatenate with +=, and a rune would not.
The parameter n in buildString is a separate variable from the n in printRhombus, because each function has its own scope. Both loops also use their own i.
When buildString gets 0, the loop doesn't run and the result is an empty string, which is exactly what the middle line needs for its spaces.
A habit worth keeping: when output must match exactly, print a line with fmt.Printf("%q\n", str) while debugging. The quotes make trailing spaces visible, so you can count them.
Complexity
There are n lines, and each is built in O(n) steps, so the time is O(n²). The output itself has n² characters, so no approach can do better. Extra space is O(n) for one line.
Edge cases and common mistakes
n = 1prints a single star:spacesis 0, so no spaces appear.- The input is promised to be odd. With an even
nthe counts no longer add up ton. Forn = 4this code prints a first line of five characters, so the shape is wrong. - Leaving out the right-hand spaces gives lines that look right on screen but differ from the expected output.
- Using
i <= n / 2for the widening test pushes the turn one line too late and prints a wrong shape. - Changing stars by 1 instead of 2 produces a lopsided figure. Each line grows by one star on each side.
Testing
For n = 3 the lines should be " * ", "***" and " * ", with the trailing space on the first and last. For n = 1 the output is *.