Reputation: 4343
Write a class that, given a positive integer N, creates and returns a square matrix NxN made out of integers that displays the numbers from 1 to n^2 in a spiral
In my class I got four methods, three of them are for the direction, while the spiral()
method should put every number in the right spot
public static int[][] spiral(int n) {
int[][] res;
int i,j;
int num;
int direction;
/** variables initializzazion */
res=new int[n][n];
i=0;
j=0;
res[i][j]=1;
direction=0;
for(num=2; num<=n*n; num++) {
direction = updateDirection(direction, i, j, n);
if ((direction==1) || (direction==3))
i=updateRow(i, direction);
else
j=updateColoumn(j, direction);
res[i][j]=num;
}
return res;
}
Sadly, when I try to run it I get an ArrayIndexOutOfBoundException
that seems to be caused by the res[i][j]=1;
.
How can I fix it so that the Array still starts from 1 and goes up to N*N?
Edit: Added updateDirection()
method
to better understand this method have a look at this image:
public static int updateDirection(int direction, int i, int j, int n) {
/** if on the secondary diagonal direction is 1 or 3 */
if(i+j==n-1)
direction++;
/** if on the lower half of the main diagonal, direction is 2 */
if(i==j && j+j>=n)
direction++;
/** if on the row below the higher half of the main diagonal, direction is 0 */
if(i==j+1 && i+j<n)
direction++;
/** in other cases, direction doesn't change */
return direction%4;
}
Edit2: This is my test method:
public static void testSpiral(){
for(int n=0; n<=5; n++)
System.out.println(Arrays.deepToString(spiral(n)));
}
Edit3: updateRow()
and updateColoumn()
methods added:
public static int updateRow(int i, int direction) {
int res;
if(direction==1)
res=i+1; //moves from top to bottom
else
res = i-1; //moves from bottom to top
return res;
}
public static int updateColoumn(int j, int direction){
int res;
if(direction==0)
res=j+1; //moves from left to right
else
res=j-1; //moves from right to left
return res;
Upvotes: 1
Views: 5006
Reputation: 1842
You do not need a class. This function returns spiral matrix in clockwise. I hope i could help.
int[][] spiralNumbers(int n) {
int[][] matrix = new int[n][n];
for (int step = 0, a = 0, size; step < n/2; step++) {
size = (n - step * 2 - 1);
for (int i = 0, chunk, chunkIndex, chunkOffset; i < 4 * size; i++) {
chunk = i / size;
chunkIndex = i % size;
chunkOffset = n - step - 1;
switch (chunk) {
case 0:
matrix[step][chunkIndex + step] = a+1;
break;
case 1:
matrix[chunkIndex + step][chunkOffset] = a+1;
break;
case 2:
matrix[chunkOffset][chunkOffset - chunkIndex] = a+1;
break;
case 3:
matrix[chunkOffset - chunkIndex][step] = a+1;
break;
default:
throw new IndexOutOfBoundsException();
}
a++;
}
if (n % 2 == 1) {
matrix[n/2][n/2] = n * n;
}
}
return matrix;
}
Upvotes: 1
Reputation: 15982
In testSpiral
method you are starting the for
loop in 0
, so the array res
is created with size 0
.
When you try to set res[i][j] = 1
you are trying to access the first element in the array but there is none.
Just start the for
in i=1
:
public static void testSpiral(){
for(int n=1; n<=5; n++)
System.out.println(Arrays.deepToString(spiral(n)));
}
Upvotes: 2
Reputation: 4322
This may or may not do what you want. I think figuring out what it does might teach you a a lot.
import java.util.Arrays;
public class Spiral {
static final int TEST_X = 5;
static final int TEST_Y = 5;
static enum Direction {UP, DOWN, LEFT, RIGHT};
public static void main( String ... args ){
for( int i = TEST_X - 1; i > 0; i--) {
for ( int j = TEST_Y - 1 ; j > 0; j-- ){
int arr[][] = spiral(i,j);
for( int[] inner : Arrays.asList(arr))
System.out.println(Arrays.toString(inner));
System.out.println("############\n");
}
}
}
public static int[][] spiral( int rows, int cols ) {
if( cols <= 0 || rows <= 0 ){
throw new IllegalArgumentException("Spiral requires dimensions greater than 0.");
}
int arr[][] = new int[rows][cols];
int count = 1;
int cur_col = -1;
int cur_row = 0;
int consecutive_turns = 0;
Direction dir = Direction.RIGHT;
while( true ) {
if( consecutive_turns == 4)
return arr;
switch( dir ){
case RIGHT :
if( cur_col + 1 == cols || arr[cur_row][cur_col + 1] > 0){
dir = Direction.DOWN;
consecutive_turns++;
} else {
consecutive_turns = 0;
cur_col++;
arr[cur_row][cur_col] = count;
count++;
}
break;
case LEFT :
if( cur_col - 1 < 0 || arr[cur_row][cur_col - 1] > 0 ){
dir = Direction.UP;
consecutive_turns++;
} else {
consecutive_turns = 0;
cur_col--;
arr[cur_row][cur_col] = count;
count++;
}
break;
case UP :
if( cur_row - 1 < 0 || arr[cur_row - 1][cur_col] > 0 ){
dir = Direction.RIGHT;
consecutive_turns++;
} else {
consecutive_turns = 0;
cur_row--;
arr[cur_row][cur_col] = count;
count++;
}
break;
case DOWN :
if( cur_row + 1 == rows || arr[cur_row + 1][cur_col] > 0 ){
dir = Direction.LEFT;
consecutive_turns++;
} else {
consecutive_turns = 0;
cur_row++;
arr[cur_row][cur_col] = count;
count++;
}
break;
default :
System.err.println("The end has come!");
System.exit(1);
}
}
}
}
Upvotes: 0