I wrote the following code to walk half the diagonals of an array:
String[][] b = [a,b,c]
[d,e,f]
[g,h,i];
public void LoopD
Type 1: We can solve this using python very easily
Code:
r,c=map(int,input().split())
mat=[[str(ch) for ch in input().split()]for _ in range(r)]
for i in range(r*c-2):
lis=[]
for j in range(r):
for k in range(c):
if k+j==i:
lis.append(mat[j][k])
print(*lis[::-1])
Output:
5 5
a b c d e
f g h i j
k l m n o
p q r s t
u v w x y
a
f b
k g c
p l h d
u q m i e
v r n j
w s o
x t
y
I wrote the following code. The key is to exhaust all of the diagonals that start at the top and then move onto the diagonals that start on the sides. I included a method that combines the two angles to traverse diagonals Northwest - Southeast and Northeast - Southwest and stand alone methods for traversing the respective angles.
public static void main(String[] args){
int[][] m = {{1,2,3},{4,5,6},{7,8,9},{10,11,12}};
printDiagonals(m, DiagonalDirection.NEtoSW, new DiagonalVisitor() {
public void visit(int x, int y, int[][] m) {
System.out.println(m[x][y]);
}
});
}
public enum DiagonalDirection{
NWToSE,
NEtoSW
}
private static abstract class DiagonalVisitor{
public abstract void visit(int x, int y, int[][] m);
}
public static void printDiagonals(int[][] m, DiagonalDirection d, DiagonalVisitor visitor){
int xStart = d==DiagonalDirection.NEtoSW ? 0 : m.length-1;
int yStart = 1;
while(true){
int xLoop, yLoop;
if(xStart>=0 && xStart<m.length){
xLoop = xStart;
yLoop = 0;
xStart++;
}else if(yStart<m[0].length){
xLoop = d==DiagonalDirection.NEtoSW ? m.length-1 : 0;
yLoop = yStart;
yStart++;
}else
break;
for(;(xLoop<m.length && xLoop>=0)&&yLoop<m[0].length; xLoop=d==DiagonalDirection.NEtoSW ? xLoop-1 : xLoop+1, yLoop++){
visitor.visit(xLoop, yLoop, m);
}
}
}
public static void printDiagonalsNEtoSW(int[][] m, DiagonalVisitor visitor){
int xStart = 0;
int yStart = 1;
while(true){
int xLoop, yLoop;
if(xStart<m.length){
xLoop = xStart;
yLoop = 0;
xStart++;
}else if(yStart<m[0].length){
xLoop = m.length-1;
yLoop = yStart;
yStart++;
}else
break;
for(;xLoop>=0 && yLoop<m[0].length; xLoop--, yLoop++){
visitor.visit(xLoop, yLoop, m);
}
}
}
public static void printDiagonalsNWtoSE(int[][] m, DiagonalVisitor visitor){
int xStart = m.length-1;
int yStart = 1;
while(true){
int xLoop, yLoop;
if(xStart>=0){
xLoop = xStart;
yLoop = 0;
xStart--;
}else if(yStart<m[0].length){
xLoop = 0;
yLoop = yStart;
yStart++;
}else
break;
for(;xLoop<m.length && yLoop<m[0].length; xLoop++, yLoop++){
visitor.visit(xLoop, yLoop, m);
}
}
}
Here is the code:
public void loopDiag(String [][] b) {
boolean isPrinted = false;
for (int i = 0 ; i < b.length ; i++) {
String temp="";
int x=i;
for(int j = 0 ; j < b.length ; j++) {
int y = j;
while (x >= 0 && y < b.length) {
isPrinted = false;
temp+=b[x--][y++];
}
if(!isPrinted) {
System.out.println(temp);
isPrinted = true;
}
}
}
}
Initialize array only for test purpose:
int dim = 5;
char ch = 'A';
String[][] array = new String[dim][];
for( int i = 0 ; i < dim ; i++ ) {
array[i] = new String[dim];
for( int j = 0 ; j < dim ; j++, ch++ ) {
array[i][j] = "" + ch;
}
}
Output our matrix:
for( int i = 0 ; i < dim ; i++ ) {
for( int j = 0 ; j < dim ; j++, ch++ ) {
System.out.print( array[i][j] + " " );
}
System.out.println();
}
System.out.println( "============================" );
Element indexes from diagonals have one rule - their sum is constant on one diagonal:
Use two loops to extract all diagonals.
First loop extracts top half of diagonals:
for( int k = 0 ; k < dim ; k++ ) {
for( int j = 0 ; j <= k ; j++ ) {
int i = k - j;
System.out.print( array[i][j] + " " );
}
System.out.println();
}
Second loop iterates on bottom half of diagonals:
for( int k = dim - 2 ; k >= 0 ; k-- ) {
for( int j = 0 ; j <= k ; j++ ) {
int i = k - j;
System.out.print( array[dim - j - 1][dim - i - 1] + " " );
}
System.out.println();
}
Use one loop to extract all diagonals, but there are extra iterations and one additional check:
for( int k = 0 ; k < dim * 2 ; k++ ) {
for( int j = 0 ; j <= k ; j++ ) {
int i = k - j;
if( i < dim && j < dim ) {
System.out.print( array[i][j] + " " );
}
}
System.out.println();
}
The output:
A B C D E
F G H I J
K L M N O
P Q R S T
U V W X Y
============================
A
F B
K G C
P L H D
U Q M I E
V R N J
W S O
X T
Y
There are questions about rectangular matrix (height != width) in comments. Here is solution for rectangular matrix:
The rule remains the same: Sum of element indexes from the same diagonal is constant
The minimum sum of indexes is 0 (for first element in matrix with indexes [0;0])
The maximum sum of indexes is width + height - 2 (for last element in matrix with indexes [height-1; with-1])
Initialize rectangular matrix only for test purpose:
int WIDTH = 7;
int HEIGHT = 3;
char ch = 'A';
String[][] array = new String[HEIGHT][];
for( int i = 0 ; i < HEIGHT ; i++ ) {
array[i] = new String[WIDTH];
for( int j = 0 ; j < WIDTH ; j++, ch++ ) {
array[i][j] = "" + ch;
}
}
Print our rectangular matrix:
for( int i = 0 ; i < HEIGHT ; i++ ) {
for( int j = 0 ; j < WIDTH ; j++, ch++ ) {
System.out.print( array[i][j] + " " );
}
System.out.println();
}
System.out.println( "============================" );
for( int k = 0 ; k <= WIDTH + HEIGHT - 2; k++ ) {
for( int j = 0 ; j <= k ; j++ ) {
int i = k - j;
if( i < HEIGHT && j < WIDTH ) {
System.out.print( array[i][j] + " " );
}
}
System.out.println();
}
Output:
A B C D E F G
H I J K L M N
O P Q R S T U
============================
A
H B
O I C
P J D
Q K E
R L F
S M G
T N
U
This is the same as what leoflower posted here. I've just changed the variable names for better understanding.
level = denotes the current level of the diagonal that is being printed. Ex:- level = 2 denotes diagonal elements with indices (0,2),(1,1),(2,0)
currDiagRowIndex = denotes row index of the current diagonal being printed
currDiagColIndex = denotes columnn index of the current diagonal being printed
void printMatrixDiagonal(int matrix[][], int endRowIndex, int endColIndex){
for(int level = 0; level < endColIndex; level++){
for(int currDiagRowIndex = 0, currDiagColIndex = level; currDiagRowIndex < endRowIndex && currDiagColIndex >= 0 ; currDiagRowIndex++, currDiagColIndex--){
System.out.print(matrix[currDiagRowIndex][currDiagColIndex] + " ");
}
System.out.println();
}
for(int level = 1; level < endRowIndex; level++){
for(int currDiagRowIndex = level, currDiagColIndex = endColIndex-1; currDiagRowIndex < endRowIndex && currDiagColIndex >= 0; currDiagRowIndex++, currDiagColIndex--){
System.out.print(matrix[currDiagRowIndex][currDiagColIndex]+ " ");
}
System.out.println();
}
}
Input:
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25
Output:
1
2 6
3 7 11
4 8 12 16
5 9 13 17 21
10 14 18 22
15 19 23
20 24
25
This is how:
int [][]mat = { {1,2,3},
{4,5,6},
{7,8,9},
};
int N=3;
for (int s=0; s<N; s++) {
for (int i=s; i>-1; i--) {
System.out.print(mat[i][s-i] + " ");
}
System.out.println();
}
for (int s=1; s<N; s++) {
for (int i=N-1; i>=s; i--) {
System.out.print(mat[i][s+N-1-i] + " ");
}
System.out.println();
}
The first loop prints the diagonals beginning from first column, the second loop prints the remaining diagonals (beginning from bottom row).
Output:
1
4 2
7 5 3
8 6
9