Diagonally print a 2D array(in all 4 directions)
Consider these 4 types of 2d arrays
let a = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]; // 3x3
let b = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]
]; // 3x4
let c = [[1, 2, 3, 4, 5]]; // 1x5
let d = [[1], [2], [3]]; // 3x1
First we will see what is the expected output if want to print these 2d arrays 1. From top-left to bottom-right
I could only align images this way on medium. Please suggest if you have any better solution (fyi i have tried grid but that just make images super huge)
Solution:
const printTopLeftToBottomRight = (arr) => {
let m = arr.length;
let n = arr[0].length;
let output = [];
for (let i = 0; i <= m + n - 2; i++) {
let j = Math.min(i, m - 1);
let x = j;
let y = i - j;
while (x >= 0 && x < m && y >= 0 && y < n) {
output.push(arr[x][y]);
--j;
x = j;
y = i - j;
}
}
console.log(output);
};
Explanation:
Let’s take the example of array B which is the most generic example among all the above. Here it takes 6 iterations to print all elements. Here what happens in each iteration:
First: 0,0
Second: 1,0 0,1
Third: 2,0 1,1 0,2
Fourth: 2,1 1,2 0,3
Fifth: 2,2 1,3
Sixth: 2,3
The pattern we can observe here is in first iteration row + column = 0, in second row + column = 1 and so on till m+n — 1 iterations. Therefore, outer-loop/first-loop will go from 0 to m+n-2. Let’s call the variable as i.
Clearly first loop will run from 0 to m+n-2. So
i: 0 to m+n-2
And in the second loop j will start from min(i, m-1) to values such value of x and y are in the bounds.
j = Math.min(i, m-1)
x = j;
y = i-j;
Decrement j such that 0≤x≤m-1 and 0≤y≤n-1
All of this translates to above code
2. From bottom-right to top-left
Solution:
const printBottomRightToTopLeft = (arr) => {
let m = arr.length;
let n = arr[0].length;
let output = [];
for (let i = m + n - 2; i >= 0; i--) {
let j = Math.min(i, m - 1);
let x = j;
let y = i - j;
while (x >= 0 && x< m && y >= 0 && y < n) {
output.push(arr[x][y]);
--j;
x = j;
y = i - j;
}
}
console.log(output);
};
Explanation:
The pattern is similar but opposite. Instead of 0 sum of row and column in first iteration is m+n-2 and of 6th is 0. So we just change order in which i changes. And rest remains same.
3. From bottom-left to top-right
Solution:
const printBottomLeftToTopRight = (arr) => {
let m = arr.length;
let n = arr[0].length;
let output = [];
for (let i = m - 1; i >= 1 - n; i--) {
let j = Math.max(0, i);
let x = j;
let y = j - i;
while (x >= 0 && x <= m - 1 && y >= 0 && y <= n - 1) {
output.push(arr[x][y]);
++j;
x = j;
y = j - i;
}
}
console.log(output);
};
Explanation:
In this scenario, the pattern we observe is
First iteration: row — column = m-1 = 2
Second iteration: row — column = 1
Third iteration: row — column = 0
Fourth iteration: row — column = -1
Fifth iteration: row — column = -2
Sixth: row — column = 1-n = -3
Clearly first loop will run from m-1 to 1-n. So
i: m-1 to 1-n
And in the second loop j will start from Math.max(0, i) to a values such value of x and y are in the bounds.
j = Math.max(0, i)
x = j;
y = j-i;
++j such that 0≤x≤m-1 and 0≤y≤n-1
All of this translates to above code
4. From top-right to bottom-left
Solution
const printTopRightToBottomLeft = (arr) => {
let m = arr.length;
let n = arr[0].length;
let output = [];
for (let i = n - 1; i >= 1 - m; i--) {
let j = Math.max(0, i);
let x = j - i;
let y = j;
while (y >= 0 && y <= n - 1 && x >= 0 && x <= m - 1) {
output.push(arr[x][y]);
++j;
x = j - i;
y = j;
}
}
console.log(output);
};
Explanation:
In this scenario, the pattern is similar but opposite.
First iteration: row — column = n-1 = 3
Second iteration: row — column = 1
Third iteration: row — column = 0
Fourth iteration: row — column = -1
Fifth iteration: row — column = 1-m = -2
therefore the loops will run in opposite direction than before
i: n-1 to 1-m
And in the second loop j will start from Math.max(0, i) to a values such value of x and y are in the bounds.
j = Math.max(0, i)
x = j-i;
y = j;
++j such that 0≤x≤m-1 and 0≤y≤n-1