Reputation: 31
I've been at this for a long time now, a few days actually, and I just can't seem to understand what's wrong with my loops!
I have to create an 'X' pattern with user input. If the user entered four, it would be like this:
X X
X X
X X
XX
XX
X X
X X
X X
It's basically a "V" stacked on top of an upside down one. But, my coding results in something really weird.
XX
XX
XX
XX
X X
X X
X X
X X
The top part only prints out the beginning spaces and the second part only prints out the middle ones!
int num = 0;
System.out.println("Enter a value between 2 and 10.");
num = keyNum.nextInt();
}
for (int a = 0; a < num; a++)
{
System.out.println("");
for (int b = 0; b <= (num - 1); b++)
{
System.out.print(" ");
}
System.out.print("X");
for (int c = num + 2; c <= 0; c -= 2)
{
System.out.print(" ");
}
System.out.print("X");
for (int d = 0; d < num; d++)
{
System.out.println("");
for (int e = (num - 1); e <= 0; e--)
{
System.out.print(" ");
}
System.out.print("X");
for (int f = 0; f <= num + 2; f += 2)
{
System.out.print(" ");
}
System.out.print("X");
}
Any kind of help would be appreciated. Thanks in advance!
Upvotes: 2
Views: 1122
Reputation: 3519
Other answers do a good job addressing the issues in the OP's code. Here is a recursive approach to the problem:
import java.util.Scanner;
public class DrawX {
public static void main(String[] args) {
int n = Integer.valueOf(new Scanner(System.in).nextLine());
//To obtain a figure similar to the OP's
drawX(2*(n - 1), 2* (n - 1), false);
}
static void drawX(int n, int limit, boolean z) {
if(Math.abs(n) > limit) return;
System.out.println(
String.join("", Collections.nCopies((limit-Math.abs(n))/2, " ")) +
"x" + //First x
String.join("", Collections.nCopies(Math.abs(n), " ")) +
"x" //Second x
);
if(n==0 && !z) drawX(n, limit, true); //This only happens once!
else drawX(n - 2, limit, false);
}
}
Execution:
10
x x
x x
x x
x x
x x
x x
x x
x x
x x
xx
xx
x x
x x
x x
x x
x x
x x
x x
x x
x x
The idea is to calculate the number of spaces needed before the first x
and the spaces between x
s for each line -both obtainable by some simple mathematical observations- and print lines recursively using String.join
and Collections.nCopies
to repeat spaces. Since the line corresponding to n=0
needs to be printed twice, we need to add a Boolean variable to keep track of when this happens.
It should be easy to convert the recursive function to a loop and I'll leave that to the OP.
Upvotes: 0
Reputation: 3020
For your spacing loops, you use a variable, num
, which doesn't change after each line. For example:
for (int b = 0; b <= (num - 1); b++)
{
System.out.print(" ");
}
This leads to the spacing staying the same throughout both outer loops. Perhaps you meant to use the loop variables a
and d
or something like that.
Upvotes: 0
Reputation: 3232
you simple add two conditions for print asterisks on both diagonals otherwise just print the space.
import java.util.Scanner;
public class XPattern {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.print("Enter a number : ");
int size = scan.nextInt();
printXPattern(size*2);
}
private static void printXPattern(int size) {
for (int i = 0; i < size ; i++) {
for (int j = 0; j < size ; j++) {
if (i == j || i + j == size - 1) {//conditions for diagonals
System.out.print("*");
} else {
System.out.print(" ");
}
}
System.out.println();
}
}
}
output :
Enter a number : 5
* *
* *
* *
* *
**
**
* *
* *
* *
* *
Upvotes: 0
Reputation: 23614
You can figure this out with some simple math. First lets plot some 2D functions.
Z = Y + X Z = Y - X
x/y| 0 1 2 3 4 5 6 7 x/y| 0 1 2 3 4 5 6 7
---|----------------------- ---|-----------------------
0 | 0 1 2 3 4 5 6 7 0 | 0 -1 -2 -3 -4 -5 -6 -7
| |
1 | 1 2 3 4 5 6 7 8 1 | 1 0 -1 -2 -3 -4 -5 -6
| |
2 | 2 3 4 5 6 7 8 9 2 | 2 1 0 -1 -2 -3 -4 -5
| |
3 | 3 4 5 6 7 8 9 10 3 | 3 2 1 0 -1 -2 -3 -4
| |
4 | 4 5 6 7 8 9 10 11 4 | 4 3 2 1 0 -1 -2 -3
| |
5 | 5 6 7 8 9 10 11 12 5 | 5 4 3 2 1 0 -1 -2
| |
6 | 6 7 8 9 10 11 12 13 6 | 6 5 4 3 2 1 0 -1
| |
7 | 7 8 9 10 11 12 13 14 7 | 7 6 5 4 3 2 1 0
You can see that the backward diagonal is determined by the invariant Z = 0 = Y - X
and the forward diagonal is determined by Z = 7 = Y + X
where 7
is 2*inputSize - 1
Putting this altogether:
int inputSize = 4;
int forwardDiagonal = inputSize*2 - 1;
for (int y = 0; y < inputSize*2; y++) {
for (int x = 0; x < inputSize*2; x++) {
if (y - x == 0) {
System.out.print("X");
} else if (y + x == forwardDiagonal) {
System.out.print("X");
} else {
System.out.print(" ");
}
}
System.out.println();
}
Upvotes: 1
Reputation: 191681
You should focus on one line at a time, then figure out the math required to get a loop
For example, first line
X X
Could be expressed by method calls (don't worry if you've not learned methods, this is only hiding the logic of the loops)
printSpaces(0); printX(); printSpaces(6); printX(); printSpaces(0);
Then, the following line, the same method calls, only different numbers
printSpaces(1); printX(); printSpaces(4); printX(); printSpaces(1);
Now, you might start to notice that the outer spaces increase by 1 each time, and the inner spaces decrease by 2.
The inner spaces will decrease by two until reaching zero, but rather than writing a backwards loop, you can actually express that mathematically in terms of the increasing outer spaces amount, 2 X's and the width of the drawn X.
inner_space = (num * 2) - 2 - (outer_spaces * 2)
For the shown examples
inner_space = (4 * 2) - 2 - (0 * 2) = 6
inner_space = (4 * 2) - 2 - (1 * 2) = 4
Therefore, you'd write a top loop like
int num = 4;
// loop 0..3
for (int outerSpace = 0; outerSpace < num; outerSpace++) {
int innerSpaces = (num * 2) - 2 - (outerSpace * 2);
// printSpaces(outerSpace);
printX();
// printSpaces(innerSpaces);
printX();
// printSpaces(outerSpace);
}
Now, whether you use methods or loops, is an implementation detail, but this is the pseudo-code for getting the top of the X
Upvotes: 0