General things
You have two loops like this:
for (int i = 1; i <= 4; i++){
for (int j = 1; j <= 12; j++){
System.out.print("~");
}
}
This is just nesting a loop for the sake of nesting a loop. I understand that the requirements state to use nested loops, but you should not make code purposefully inefficient just for the sake of it. This should just be for (int i = 1; i <= 48; i++)
You are doing System.out.print()
a lot. Your code would be more clear if you used something like a StringBuilder
, and append characters to it, and only print it once at the end after it is completed:
class Exercises {
public static void main (String[] args){
StringBuilder output = new StringBuilder("");
for (int i = 1; i <= 48; i++){
output.append("~");
}
output.append("\n");
output.append("~");
//etc.
System.out.print(output);
}
}
}
Approach
The approach you have is not ideal, as has been addressed by others answers. I will take a grounds-up approach as to how I think would be a good way to approach a problem like this.
There are some things we know about the required pattern that we can declare as constants, as they will never change.
- The length of the lines (48)
- The number of lines (4)
- That each line has its own pattern (the pattern itself is not very important)
And some things we can infer, by doing basic armchair math and just looking at the lines.
- 48 is divisible by 2, 3, 4, 8, 12, 16, etc.
- Necessarily a pattern is going to be one of those, if we are going to divide the line evenly
- By looking at each line more closely, it looks like the smallest observable pattern is 3.
So, let's declare all this at the top:
final int NUMBER_OF_LINES = 4;
final int LINE_LENGTH = 48;
final int PATTERN_LENGTH = 3;
final String[] LINE_NUMBER_PATTERNS = {"~~~","~+~","+~+","~~~"};
So we know how long each line is, and how many times to iterate each pattern, and that we will need to first iterate over each line, and then iterate over the characters per line. So, the skeleton might look like this:
for (int currentLine = 1; currentLine <= NUMBER_OF_LINES; currentLine++) {
for (int i = 1; i <= LINE_LENGTH; i += PATTERN_LENGTH) {
// do some stuff here
}
}
You also noticed I made a String[]
which is an array of strings containing a pattern for each line. The patterns could be any string of characters, and of any length. Arrays are 0
-indexed, so we will use 0
to 3
to count the lines, instead of 1
to 4
. (notice the use of <
instead of <=
, as we want to stop at index 3
which is the 4th line)
for (int currentLine = 0; currentLine < NUMBER_OF_LINES; currentLine++) {
for (int i = 1; i <= LINE_LENGTH; i += PATTERN_LENGTH) {
output.append(LINE_NUMBER_PATTERNS[currentLine]);
}
}
It outputs this, which is almost correct:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+~~+~~+~~+~~+~~+~~+~~+~~+~~+~~+~~+~~+~~+~~+~~+~+~++~++~++~++~++~++~++~++~++~++~++~++~++~++~++~+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
So, all we are missing is a line break "\n"
at the end of each line, after we exit the inner loop. So everything all said and done, this is what we have, and it works perfectly. (demo on ideone.com)
class Main {
public static void main (String[] args){
final int NUMBER_OF_LINES = 4;
final int LINE_LENGTH = 48;
final int PATTERN_LENGTH = 3;
final String[] LINE_NUMBER_PATTERNS = {"~~~","~+~","+~+","~~~"};
StringBuilder output = new StringBuilder("");
int index;
for (int currentLine = 1; currentLine <= NUMBER_OF_LINES; currentLine++) {
index = currentLine -1;
for (int i = 1; i <= LINE_LENGTH; i += PATTERN_LENGTH) {
output.append(LINE_NUMBER_PATTERNS[index]);
}
output.append("\n");
}
System.out.print(output);
}
}