I'm writing the following program for a school assignment. The prompt is as follows:
A magic square is square grid filled with distinct positive integers such that each cell contains a different integer and the sum of the integers in each row, column and diagonal is equal.
My task is to make a boolean method, named magical()
that is passed a 2d array, and will return true
if those criteria are met. This is the code I wrote:
private static boolean magical(int[][] square) {
int length = square.length;
//This loop checks for duplicate values
for (int i = 0; i < length; i++){
for (int j = 0; j < length; j++){
int x = square[i][j];
for (int a = 0; a < length; a++){
for (int b = 0; b < length; b++){
if (a == i && b == j) continue;
if (x == square[a][b]) return false;
}
}
}
}
ArrayList<Integer> sums = new ArrayList<>();
//This loop finds the sums of the rows and columns
for (int i = 0; i < length; i++){
int sum = 0;
int sum2 = 0;
for (int j = 0; j < length; j++){
sum += square[i][j];
sum2 += square[j][i];
}
sums.add(sum);
sums.add(sum2);
}
//The next two loops find the sums of each diagonal.
int x = 0;
int y = 0;
int sum = 0;
while (x < length && y < length){
sum += square[x][y];
x++;
y++;
}
sums.add(sum);
sum = 0;
x = 0;
y = length - 1;
while (x < length && y >= 0){
sum += square[x][y];
x++;
y--;
}
sums.add(sum);
return sums.stream().allMatch(s -> s.equals(sums.get(0)));
}
Here are my questions:
Is there any way to confirm that there are no duplicate values in the array without having to nest four for loops? This seems like an incredibly inefficient system.
Is there any way to combine the two loops in the end that are used to make sure that the sum of values in each diagonal are the same? I am currently using two loops, but seeing as I am iterating through the same array, it seems inefficient to do it twice.
I am also open to any other suggestions you may have. Please note, it is given in the prompt that all arrays passed as parameters will be squares, and it is not required to test for this.