Given a number x, insert elements 1 to x^2 in a matrix spirally.
e.g. For x = 3, matrix looks like [[1,2,3],[8,9,4],[7,6,5]].
For this I've written following snippet. However, I'm getting o/p as [[7,9,5],[7,9,5],[7,9,5]]
while(t<=b && l<=r){
System.out.print(t+" "+b+" "+l+" "+r+"\n");
if(dir==0){
for(int i = l;i<=r;i++){
arr.get(t).set(i,x);
x++;
}
t++;
}else if(dir==1){
for(int i = t;i<=b;i++){
arr.get(i).set(r,x);
x++;
}
r--;
}else if(dir==2){
for(int i = r;i>=l;i--){
arr.get(b).set(i,x);
x++;
}
b--;
}else if(dir==3){
for(int i = b;i>=t;i--){
arr.get(l).set(i,x);
x++;
}
l++;
}
dir = (dir+1)%4;
}
You can use the next code (which I developed for some implementation that handles huge martrix sizes). It will use width (columns) and height (rows) of any matrix size and produce the output you need
List<rec> BuildSpiralIndexList(long w, long h)
{
List<rec> result = new List<rec>();
long count = 0,dir = 1,phase = 0,pos = 0;
long length = 0,totallength = 0;
bool isVertical = false;
if ((w * h)<1) return null;
do
{
isVertical = (count % 2) != 0;
length = (isVertical ? h : w) - count / 2 - count % 2;
phase = (count / 4);
pos = (count % 4);
dir = pos > 1 ? -1 : 1;
for (int t = 0; t < length; t++)
// you can replace the next code with printing or any other action you need
result.Add(new rec()
{
X = ((pos == 2 || pos == 1) ? (w - 1 - phase - (pos == 2 ? 1 : 0)) : phase) + dir * (isVertical ? 0 : t),
Y = ((pos <= 1 ? phase + pos : (h - 1) - phase - pos / 3)) + dir * (isVertical ? t : 0),
Index = totallength + t
});
totallength += length;
count++;
} while (totallength < (w*h));
return result;
}
This solution walks from the top left to the top right, the top right to the bottom right, the bottom right to the bottom left and the bottom left up to the top left.
It is a tricky problem, hopefully my comments below assist in explaining.
Below is a codepen link to see it added to a table.
https://codepen.io/mitchell-boland/pen/rqdWPO
const n = 3; // Set this to a number
matrixSpiral(n);
function matrixSpiral(number){
// Will populate the outer array with n-times inner arrays
var outerArray = [];
for(var i = 0; i < number; i++){
outerArray.push([]);
}
var leftColumn = 0;
var rightColumn = number - 1;
var topRow = 0;
var bottomRow = number-1;
var counter = 1; // Used to track the number we are up to.
while(leftColumn <= rightColumn && topRow <=bottomRow){
// populate the top row
for(var i = leftColumn; i <= rightColumn; i++){
outerArray[leftColumn][i] = counter;
counter++;
}
// Top row is now populated
topRow ++;
// Populate the right column
for(var i = topRow ; i <= bottomRow; i++){
outerArray[i][rightColumn] = counter;
counter++;
}
// Right column now populated.
rightColumn--;
// Populate the bottom row
// We are going from the bottom right, to the bottom left
for(var i = rightColumn; i >= leftColumn; i--){
outerArray[bottomRow][i] = counter;
counter++;
}
// Bottom Row now populated
bottomRow--;
// Populate the left column
// We are going from bottom left, to top left
for(var i = bottomRow; i >= topRow ; i--){
outerArray[i][leftColumn] = counter;
counter++;
}
// Left column now populated.
leftColumn++;
// While loop will now repeat the above process, but a step in.
}
// Console log the results.
for(var i = 0; i < number; i++){
console.log(outerArray[i]);
}
}