Start learning free

LESSON 178 OF 338 · FUNCTIONS & CLASSES

Print Rhombus in Go: Loops, Counters and a Helper

Practice O(n2) Read the full explanation

Given an odd positive integer n print a rhombus of stars as in the example below

Example:

Input: n = 5
Output:
  *  
 *** 
*****
 *** 
  *  

Explanation:
There are n = 5 lines. Each line contains exactly n = 5 characters.
1st line contains two spaces, one '*' and two spaces.
2nd line contains one space, three '*' and one space.
3rd line contains five stars.
4th line contains one space, three '*' and one space.
5th line contains two spaces, one '*' and two spaces.
Note: Be careful to add the necessary spaces at the end of every line!


STEP 1 OF 7
    Ctrl + Enter to check

    GO · FUNCTIONS & CLASSES

    Print Rhombus in Go, explained

    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

    1. Declare stars as 1 and spaces as n / 2. With integers, 5 / 2 is 2, and for odd n this is exactly the number of spaces needed.
    2. Loop i from 0 while i < n: one pass per line.
    3. In the loop, join the spaces, stars and spaces, each from buildString, into str and print it with fmt.Println. A line ending in + continues on the next line.
    4. Update the counters for the next line. If i < n / 2 the shape is still widening, so add 2 to stars and subtract 1 from spaces. Otherwise subtract 2 from stars and add 1 to spaces.
    5. Write buildString(n int, character string) string below printRhombus. It starts from an empty string, loops n times appending character, 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 = 1 prints a single star: spaces is 0, so no spaces appear.
    • The input is promised to be odd. With an even n the counts no longer add up to n. For n = 4 this 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 / 2 for 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 *.

    Keep going with GoAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free