# Spiral filling an existing matrix in their respective positions in descending order efficiently

Question:

• Sort the boundary elements in descending order using any standard sorting technique and rearrange them in the matrix.

• Calculate the sum of the boundary elements.

• Display the original matrix, rearranged matrix and sum of the boundary elements.

Code:

import java.util.*;
class SortBoundary
{
int A[][], B[], m, n;
static int sum=0;

void input() //Function for taking all the necessary inputs
{
Scanner sc = new Scanner(System.in);
System.out.print("Enter the size of the square matrix : ");
m=sc.nextInt();
if(m<4 || m>10)
{
System.out.println("Invalid Range");
System.exit(0);
}
else
{
A = new int[m][m];
n = m*m;
B = new int[n]; // 1-D Array to store Boundary Elements

System.out.println("Enter the elements of the Matrix : ");
for(int i=0;i<m;i++)
{
for(int j=0;j<m;j++)
{
System.out.print("Enter a value : ");
A[i][j]=sc.nextInt();
}
}
}
}

/* The below function is used to store Boundary elements
* from array A[][] to array B[]
*/
void convert()
{
int x=0;
for(int i=0;i<m;i++)
{
for(int j=0;j<m;j++)
{
if(i == 0 || j == 0 || i == m-1 || j == m-1) // Condition for boundary elements
{
B[x] = A[i][j];
x++;
sum = sum + A[i][j]; // Finding sum of boundary elements
}
}
}
}

void sortArray() //Function for sorting Boundary elements stored in array B[]
{
int c = 0;
for(int i=0; i<n-1; i++)
{
for(int j=i+1; j<n; j++)
{
if(B[i]<B[j]) // for ascending use B[i]>B[j]
{
c = B[i];
B[i] = B[j];
B[j] = c;
}
}
}
}

/* Function fillSpiral is filling the boundary of 2-D array in spiral
* way from the elements of 1-D array
*/
void fillSpiral()
{
int R1=0, R2=m-1, C1=0, C2=m-1, x=0;

for(int i=C1;i<=C2;i++) // accessing the top row
{
A[R1][i]=B[x++];
}
for(int i =R1+1;i<=R2;i++) // accessing the right column
{
A[i][C2]=B[x++];
}
for(int i =C2-1;i>=C1;i--) // accessing the bottom row
{
A[R2][i]=B[x++];
}
for(int i =R2-1;i>=R1+1;i--) // accessing the left column
{
A[i][C1]=B[x++];
}
}

void printArray() //Function for printing the array A[][]
{
for(int i=0;i<m;i++)
{
for(int j=0;j<m;j++)
{
System.out.print(A[i][j]+"\t");
}
System.out.println();
}
}

public static void main(String args[])
{
SortBoundary ob = new SortBoundary();
ob.input();
System.out.println("*********************");
System.out.println("The original matrix:");
System.out.println("*********************");
ob.printArray(); //Printing the original array
ob.convert(); //Storing Boundary elements to a 1-D array
ob.sortArray(); //Sorting the 1-D array (i.e. Boundary Elements)
ob.fillSpiral(); //Storing the sorted Boundary elements back to original 2-D array

System.out.println("*********************");
System.out.println("The Rearranged matrix:");
System.out.println("*********************");
ob.printArray(); //Printing the rearranged array
System.out.println("*********************");
System.out.println("The sum of boundary elements is = "+sum); //Printing the sum of boundary elements
}
}


What I want to accomplish:

I want to fill the original array A with the sorted boundary elements B in a single loop at their respective positions in descending order.In my code I have used 4 different loops for accomplishing this task.Any suggestions or help to make my code better?

• Cross-posted on Stack Overflow
– Mast
Commented Feb 5, 2018 at 16:36
• Does your code currently work as expected? As in, does it do the job?
– Mast
Commented Feb 5, 2018 at 16:37
• Yes.i want to improve it.
– user159829
Commented Feb 5, 2018 at 16:38

Have no idea what's your question but here is a short method that's placing a boarder to a matrix. You could use the a as index for the B array.

private static void placeBoarders(int[][] matrix, int n) {
int a = 0;

for (int i = 0; i < 4 * (n-1); i++) {
switch (i/(n - 1)) {
case 0:
matrix[i%(n-1)][0] = a;
break;
case 1:
matrix[n-1][i%(n-1)] = a;
break;
case 2:
matrix[(n - 1) - i%(n-1)][n-1] = a;
break;
case 3:
matrix[0][(n-1) - i%(n-1)] = a;
break;
default:
throw new IndexOutOfBoundsException();
}
a++;
}
}


The logic I've used here is that if I split the boarder to four equal chunks and I start from (top left -> bottom left -> bottom right -> top right -> top left) then I will have four pieces of size n-1. If you write it dawn on a paper then it will take like 5 mins to calculate the indexes.

For the opposite direction (top left -> top right -> bottom right -> bottom left -> top left) you should swap the matrix indexes just like this:

matrix[i%(n-1)][0] >> matrix[0][i%(n-1)]
matrix[n-1][i%(n-1)] >> matrix[i%(n-1)][n-1]
matrix[(n - 1) - i%(n-1)][n-1] >> matrix[n-1][(n - 1) - i%(n-1)]
matrix[0][(n-1) - i%(n-1)] >> matrix[(n-1) - i%(n-1)][0]


and even add some more clarity I will define some variables so the things get a bit clear for you:

private static void placeBoarders(int[][] matrix, int n) {
for (int i = 0, size = (n - 1), a = 0, chunk, chunkIndex; i < 4 * size; i++) {
chunk = i / size;
chunkIndex = i % size;
switch (chunk) {
case 0:
matrix[0][chunkIndex] = a;
break;
case 1:
matrix[chunkIndex][size] = a;
break;
case 2:
matrix[size][size - chunkIndex] = a;
break;
case 3:
matrix[size - chunkIndex][0] = a;
break;
default:
throw new IndexOutOfBoundsException();
}
a++;
}
}


Here instead of using matrix[X][Y] = a, you should use a as index for the sorted B array so it will be like matrix[X][Y] = B[a];

If you need to take the indexes of the the matrix starting from (0,0) in the direction ( top left -> top right -> bottom right -> bottom left -> top right) then you could use this code :

private static void fillSpiralMatrix(int[][] matrix, int 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;
break;
case 1:
matrix[chunkIndex + step][chunkOffset] = a;
break;
case 2:
matrix[chunkOffset][chunkOffset - chunkIndex] = a;
break;
case 3:
matrix[chunkOffset - chunkIndex][step] = a;
break;
default:
throw new IndexOutOfBoundsException();
}
a++;
}
if (n % 2 == 1) {
matrix[n/2][n/2] = n * n - 1;
}
}
}


In this case we do define

• My array A has the original array and Array B has the boundary elements of which I have found out the sum and also sorted it .Now my task is to fill the elements of array B in array A spirally.Why spirally you might ask? This is because I have to show the original array elements with the boundary elements .
– user159829
Commented Feb 6, 2018 at 1:32
• If I get it right you have to fill the whole matrix not only the boarders ? is that correct :?
– dbl
Commented Feb 6, 2018 at 8:31
• yes.Only the borders should be in descending order.For example consider the border matrix has [25,23,15,9,0,-2....] then 25 should be at (0,0) coordinates and like that the other elements should be arranged in a spiral order.
– user159829
Commented Feb 6, 2018 at 8:47
• I will edit my answer but still not sure if I got your point correctly :)
– dbl
Commented Feb 6, 2018 at 9:20
• Sorry I meant circular filling of boundaries in descending order not spiral.
– user159829
Commented Feb 6, 2018 at 9:22