Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a looping square with java

Tags:

java

loops

Full Disclosure: Homework.

Explanation: I cant understand my teacher.

Problem:

Write a method called printSquare that takes in two integer parameters, a min and a max, and prints the numbers in the range from min to max inclusive in a square pattern. The square pattern is easier to understand by example than by explanation, so take a look at the sample method calls and their resulting console output in the table below. Each line of the square consists of a circular sequence of increasing integers between min and max. Each line prints a different permutation of this sequence. The first line begins with min, the second line begins with min + 1, and so on. When the sequence in any line reaches max, it wraps around back to min. You may assume the caller of the method will pass a min and a max parameter such that min is less than or equal to max

enter image description here

I cannot for the life of me figure out how to make the numbers stop at the 'max' value and start over in the middle of the line.

This is what I have so far, apologies but I have trouble with for loops.

for(int i = 0; i < row; i++)
{
    for(int d = 0; d < row; d++)
    {
        System.out.print(d+1);
    }
    System.out.println(i);
}

I know I used row twice, but its the only way i can get the compiler to form a square shape with the loop. Does anyone even remotely understand what i'm trying to do? :/

like image 468
Christopher Baldwin Avatar asked Nov 05 '13 15:11

Christopher Baldwin


People also ask

How do you create a square pattern in Java?

Step 1: Input number of rows and columns. Step 2: For rows of rectangle run the outer loop from 1 to rows. Step 3: For the column of the rectangle run the inner loop from 1 to columns. Step 4: Print star for first or last row or for first or last column, otherwise print blank space.


3 Answers

This is actually a nice mathematical problem. Assume:

int side = to - from + 1; /// the size/width of the square.

the value at any point in the square (row, col) is:

from + ((row + col) % side)

you should be able to put that in your loops and "smoke it".


Edit based on comment asking for explanation.

The trick is to loop through all the positions in the 'matrix'. Given that the matrix is square, the loops are relatively simple, just two loops (nested) that traverse the system:

    final int side = to - from + 1;
    for (int row = 0; row < side; row++) {
        for(int col = 0; col < side; col++) {
            ... magic goes here....
        }
    }

Now, in this loop, we have the variables row and col which represent the cell in the matrix we are interested in. The value in that cell needs to be proportional to the distance it is from the origin..... let me explain.... If the origin is the top left (which it is), then the distances from the origin are:

0 1 2 3 4
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8

The distance is the sum of the row and the column...... (rows and columns start counting from 0).

The values we put in each matrix are limited to a fixed range. For the above example, with a square of size 5, it could have been specified as printSquare(1,5).

The value in each cell is the from value (1 in this example) plus the distance from the origin... naively, this would look like:

1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8
5 6 7 8 9

here the values in the cell have exceeded the limit of 5, and we need to wrap them around... so, the trick is to 'wrap' the distances from the origin..... and the 'modulo' operator is great for that. First, consider the original 'origin distance' matrix:

0 1 2 3 4
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8

if we instead populate this matrix with 'the remainder of the distance when dividing by 5' (the modulo 5, or %5) we get the matrix:

0 1 2 3 4
1 2 3 4 0
2 3 4 0 1
3 4 0 1 2
4 0 1 2 3

Now, if we add this 'modulo' result to the from value (1), we get our final matrix:

1 2 3 4 5
2 3 4 5 1
3 4 5 1 2
4 5 1 2 3
5 1 2 3 4

in a sense, all you need to know is that the value at each cell is:

the from value plus the remainder when you divide the 'distance' by the width.

Here's the code I tested with:

public static final String buildSquare(final int from, final int to) {
    final StringBuilder sb = new StringBuilder(side * side);

    final int side = to - from + 1;

    for (int row = 0; row < side; row++) {
        for(int col = 0; col < side; col++) {
            sb.append( from + ((row + col) % side) );
        }
        sb.append("\n");
    }
    return sb.toString();

}

public static void main(String[] args) {
    System.out.println(buildSquare(1, 5));
    System.out.println(buildSquare(3, 9));
    System.out.println(buildSquare(5, 5));
    System.out.println(buildSquare(0, 9));
    System.out.println(buildSquare(0, 3));
}
like image 62
rolfl Avatar answered Oct 22 '22 21:10

rolfl


Since this is homework, I'll just give a hint.

I cannot for the life of me figure out how to make the numbers stop at the 'max' value and start over in the middle of the line.

Here's one way to do it.

  • Create the first number twice in an array. Taking the printSquare(1, 5) example, create an int array of 1, 2, 3, 4, 5, 1, 2, 3, 4, 5.

  • Use a loop to loop through the array, starting with element zero and ending with element 4, and another loop to display 5 digits (max - min + 1).

like image 26
Gilbert Le Blanc Avatar answered Oct 22 '22 21:10

Gilbert Le Blanc


try this

    int i,j,k;
    for(i=min;i<=max;i++) {
        for(j=i;j<=max;j++) {
            System.out.print(j);
        }
        for(k=min;k<i;k++){
            System.out.print(k);
        }
        System.out.println();
    }
like image 2
Thirumalai Parthasarathi Avatar answered Oct 22 '22 20:10

Thirumalai Parthasarathi