Problem overview
The method printRhombus receives an odd positive integer n and prints a rhombus of stars, one line per row, using println. The rhombus has exactly n lines, and every line is exactly n characters long. A line is made of spaces on the left, a run of stars in the middle and spaces on the right.
For n = 5 the output is:
*
***
*****
***
*
The spaces at the end of each line are part of the output. The first line is two spaces, one star and two spaces. Leaving the right-hand spaces out makes the lines different from what the lesson's tests expect.
Approach: track two numbers
Look at how the lines change. In the top half, each line has two more stars than the one above it and one space fewer on each side. After the middle line, the changes reverse. So the whole shape is described by two numbers per line: the count of stars and the count of spaces on each side.
The program keeps both numbers in variables, prints a line from them, and then updates them for the next line. The first line has one star and n / 2 spaces on each side. With n = 5, that is 5 / 2, which is 2 because dividing two Int values in Scala drops the remainder. Since n is odd, the line width is always spaces + stars + spaces = n.
Building a string of repeated characters is needed three times per line, so it goes into a small helper, buildString. The same helper makes a run of spaces and a run of stars.
Step by step
- Declare
starsas avarset to 1. It changes on every line, sovalwould not work. - Declare
spacesas avarset ton / 2. This is the number of spaces on each side of the first line. - Loop with
for (i <- 0 until n). The range0 until nexcludesn, so the body runs exactlyntimes, once per line. - Build the line from three pieces: left spaces, stars, right spaces. Join them with
+and print the result. When a line ends with+, Scala knows the expression continues on the next line. - Update the counters for the next line. While
i < n / 2, the shape is still growing: add 2 tostarsand subtract 1 fromspaces. Otherwise, it shrinks: subtract 2 fromstarsand add 1 tospaces. - Write
buildString(n, character). It takes anIntand aCharand returns aString. - Fill it with a loop. Start from an empty
varstring, appendcharacteronce per iteration, and return the string.
The middle line is the turning point. When i equals n / 2, the condition i < n / 2 is false, so the middle line is the first one to take the else branch. It prints with the full width of stars, and the update after it starts the narrowing.
The solution in Scala
class Solution {
def buildString(n: Int, character: Char): String = {
var str = ""
for (i <- 0 until n) {
str += character
}
return str
}
def printRhombus(n: Int): Unit = {
var stars = 1
var spaces = n / 2
for (i <- 0 until n) {
val str = buildString(spaces, ' ') +
buildString(stars, '*') +
buildString(spaces, ' ')
println(str)
if (i < n / 2) {
stars += 2
spaces -= 1
} else {
stars -= 2
spaces += 1
}
}
}
}
The Scala details worth a closer look:
CharandStringuse different quotes.' 'and'*'are singleCharvalues, while"x"would be aString.str += characterworks on aStringand appends the character to the end of it.- Strings are immutable.
str += characteris shorthand forstr = str + character: it builds a new string and stores it in thevar. That is fine for these short lines. For long strings,"*" * 5, which gives"*****", does the same job in one step. - The loop variable. In
for (i <- 0 until n), theiis a freshvalon every iteration. InbuildStringthe loop variable is never read, because the loop only counts repetitions. returnis optional. The last expression of a block is its value, so the final line could be juststr. The explicitreturn stris allowed and does the same thing.- Methods can call each other in any order.
printRhombususesbuildStringthrough the same class, and the order in which they are written doesn't matter.
Complexity
Time: O(n²). The program prints n lines, and each line is n characters long, so the output alone has n² characters. Building each line with buildString does work proportional to the line width.
Space: O(n). Only one line is held in memory at a time, plus a few integers.
Edge cases and common mistakes
- Missing right-hand spaces. A line with only the left spaces and the stars is shorter than
n. Every line must end with its spaces. - Using
valfor the counters. The update step would not compile, because avalcan't be reassigned. - Using
i <= n / 2in the update. The middle line would still widen the shape, so the line after it would haven + 2stars. n = 1. The loop runs once and prints a single*. The updates then run once and give values that are never used.- Even
n. The lesson only gives odd values. With an evenn, the line widths would not matchn, because the star counts are always odd. - Counting
starsin the wrong steps. Each line changes by two stars, one for each side. Changing by one would leave the line width different fromn.
Testing
n = 1prints*.n = 3prints*,***and*on three lines.n = 5prints the five lines shown above.
