Your logic is completely static and will be impossible to maintain for bigger shape, but that kind of shape have a specific pattern.
The pattern
For a height (4), the output should be : (space replace by a dot for readability).
...*
..*.*
.*...*
* * * *
We can see that the left spaces start at 3 (height - 1) and decreased by one each time.
When we have two stars, the spaces between those is odd, incremented by two each row. If we use a bigger triangle, we see the following pattern :
- 1 space //Row 1 (using an 0-index based, first row don't have that spaces)
- 3 spaces //Row 2
- 5 spaces //Row 3
- 7 spaces //Row 4
This can be calculated with (#row * 2 - 1)
The last row is a bit different, we need to print 4 stars (height) separated by a space
Let's code
First, we need a way to easily print a number of spaces (the only variable in that pattern).
public static String blankString(int length);
The method can be quite verbose using a loop but I like to use String.format
here. This formatting allow use to add space padding to a String
easily. More information can be found at How can I pad a String in Java?
public static String blankString(int length){
if(length == 0)
return ""; //%0s is not supported
else
return String.format("%" + length + "s", "");
}
A one-line method using a ternary operator, because it is nice to use
return (length == 0) ? "" : String.format("%" + length + "s", "");
The triangle
*
* *
* *
* * * *
Let's use the previous method to print the triangle like explained before
System.out.println(blankString(3) + "*"); // ...*
System.out.println(blankString(2) + "*" + blankString(1) + "*"); // ..*.*
System.out.println(blankString(1) + "*" + blankString(3) + "*"); // .*...*
for(int i = 0; i < 4; ++i){
System.out.print("* "); //*.*.*.*.
}
Great, this works, know let's update the code with a variable height
.
int height = 4;
System.out.println(blankString(height - 1) + "*"); //Row 0
System.out.println(blankString(height - 1 - 1) + "*" + blankString((1 * 2) - 1) + "*"); //Row 1
System.out.println(blankString(height - 1 - 2) + "*" + blankString((2 * 2) - 1) + "*"); //Row 2
for(int i = 0; i < height; ++i){
System.out.print("* ");
}
Note that we find the row#
in the parameter send to blankString
int height = 4;
//Row 0
System.out.println(blankString(height - 1) + "*");
// Following rows
for(int row = 1; row < height -1 ; ++row){
System.out.println(blankString(height - 1 - row) + "*" + blankString((row * 2) - 1) + "*"); //Row 1
}
//Last row
for(int i = 0; i < height; ++i){
System.out.print("* ");
}
Of course, we end up with a method two allow us to change height
public static void buildTriangle(int height){
//Row 0
System.out.println(blankString(height - 1) + "*");
// Following rows
for(int row = 1; row < height -1 ; ++row){
System.out.println(blankString(height - 1 - row) + "*" + blankString((row * 2) - 1) + "*"); //Row 1
}
//Last row
for(int i = 0; i < height; ++i){
System.out.print("* ");
}
}
And with buildTriangle(8)
:
*
* *
* *
* *
* *
* *
* *
* * * * * * * *
Note, most of the code need to be protected against negative parameters, but since this pattern was not easy to explain, I preferred to focus the scope on the logic, not the parameter safety.