-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathResult.java
More file actions
126 lines (102 loc) · 4.44 KB
/
Result.java
File metadata and controls
126 lines (102 loc) · 4.44 KB
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
package hackrank.algorithm.implement.rotate;
import java.util.ArrayList;
import java.util.List;
/**
* @see <a href="https://www.hackerrank.com/challenges/matrix-rotation-algo">Matrix Layer Rotation</a>
*/
public class Result {
/**
* @param matrix 2D list of integers.
* @param rotations Number of times to rotate in anti-clockwise direction.
*/
public static void matrixRotation(List<List<Integer>> matrix, int rotations) {
rotateMatrixLayers(matrix, rotations);
System.out.println(getStringDisplay(matrix));
}
public static void rotateMatrixLayers(List<List<Integer>> matrix, int rotations) {
List<MatrixLayer> layers = getLayers(matrix);
for (MatrixLayer layer : layers) {
int rotate = rotations % layer.numberCells;
for (int i = 0; i < rotate; i++) {
rotateLayer(matrix, layer);
}
}
}
private static List<MatrixLayer> getLayers(List<List<Integer>> matrix) {
List<MatrixLayer> layers = new ArrayList<>();
int matrixRows = matrix.size();
int matrixColumns = matrix.get(0).size();
for (int layerIndex = 0; layerIndex < matrixRows; layerIndex++) {
int layerRows = matrixRows - 2 * layerIndex;
int layerColumns = matrixColumns - 2 * layerIndex;
if (layerRows > 1 && layerColumns > 1) {
layers.add(new MatrixLayer(layerIndex, layerRows, layerColumns));
}
}
return layers;
}
private static void rotateLayer(List<List<Integer>> matrix, MatrixLayer layer) {
int rowIndex = layer.rowIndexMin;
int columnIndex = layer.columnIndexMin;
int replaced = matrix.get(rowIndex).get(columnIndex);
for (int i = 0; i < layer.numberCells; i++) {
int[] nextCell = layer.getNextCell(rowIndex, columnIndex);
int rowNext = nextCell[0];
int colNext = nextCell[1];
int temp = matrix.get(rowNext).get(colNext);
matrix.get(rowNext).set(colNext, replaced);
replaced = temp;
columnIndex = colNext;
rowIndex = rowNext;
}
}
/**
* Helper method to display {@code matrix} as a string.
*/
static String getStringDisplay(List<List<Integer>> matrix) {
StringBuilder sb = new StringBuilder();
for (int rowIndex = 0; rowIndex < matrix.size(); rowIndex++) {
if (rowIndex > 0) {
sb.append(System.lineSeparator());
}
for (int columnIndex = 0; columnIndex < matrix.get(0).size(); columnIndex++) {
if (columnIndex > 0) {
sb.append(" ");
}
sb.append(matrix.get(rowIndex).get(columnIndex));
}
}
return sb.toString();
}
private static class MatrixLayer {
private final int rowIndexMin;
private final int rowIndexMax;
private final int columnIndexMin;
private final int columnIndexMax;
private final int numberCells;
MatrixLayer(int index, int numberRows, int numberColumns) {
this.rowIndexMin = index;
this.rowIndexMax = index + numberRows - 1;
this.columnIndexMin = index;
this.columnIndexMax = index + numberColumns - 1;
this.numberCells = 2 * (numberRows + numberColumns - 2);
}
/**
* @return Row and column index of next cell in anti-clockwise direction.
*/
int[] getNextCell(int currentRowIndex, int currentColumnIndex) {
int nextRowIndex = currentRowIndex;
int nextColumnIndex = currentColumnIndex;
if (currentRowIndex == rowIndexMin && currentColumnIndex > columnIndexMin) {
nextColumnIndex += -1; // column index moves right to left along row
} else if (currentColumnIndex == columnIndexMax && currentRowIndex > rowIndexMin) {
nextRowIndex += -1; // row index moves bottom to top along column
} else if (currentRowIndex == rowIndexMax && currentColumnIndex < columnIndexMax) {
nextColumnIndex += 1; // column index moves left to right along row
} else if (currentColumnIndex == columnIndexMin && currentRowIndex < rowIndexMax) {
nextRowIndex += 1; // row index moves top to bottom along column
}
return new int[] { nextRowIndex, nextColumnIndex };
}
}
}