I'm kinda stuck on what to do with this square matrix coding project.
Whenever I try to input any values, the results always turn out as true and that the square matrix is a magic square. For example, this would turn out true:
16 03 02 13
05 10 11 08
09 06 07 12
04 15 14 01
but when I input values like:
03 04 16 02
05 01 02 10
05 08 07 12
03 14 13 09
This should return false but it still returns true saying that it is a magic square.
The requirements are that I need all the methods
"public void add(int i, int row, int col)": Adds an integer to the matrix at the specified location.
public
"public boolean allInRange": Determines whether all values in the matrix are in the proper range
"public boolean allUnique": Determines whether all values in the matrix appear only once
"public boolean isMagic": Determines whether the matrix illustrates a magic square. This means:
The user entered n^2 numbers for some number n
The numbers are only between 1 and n^2, inclusive
Each of the numbers occurs exactly once in the matrix
The sums of the elements in each row, column, and the two diagonals are equal
public class SquareMatrix {
private int[][] array;
public SquareMatrix(int size)
{
array = new int[size][size];
}
public void add(int i, int row, int column) {array[row][column] = i;}
//Just checks if the #of rows & columns are between 1-n^2
public boolean allInRange()
{
int n = array.length;
for (int row = 0; row < n; row++)
{
for (int col = 0; col < array[row].length; col++)
{
if (array[row][col] < 1 || array[row][col] > n*n)
return false;
}
}
return true;
}
public boolean allUnique()
{
for (int i =0; i < array.length - 1; i++)
{
for (int j = i + 1; j < array.length; j++)
{
if(array[i]==array[j])
return false;
}
}
return true;
}
//Supposed to call the other methods (allInRange & allUnique)
public boolean isMagic()
{
for(int[] row : array)
{
for (int num : row)
{
if (num == 0)
return false;
}
}
boolean range = allInRange();
if (range == true)
return true;
if (range == false)
return false;
boolean unique = allUnique();
if (unique == true)
return true;
if (unique == false)
return false;
int sumRow;
int sumCol;
int sum1 = 0;
int sum2 = 0;
//Sum of Left to Right Diaganol
for (int i = 0; i < array.length; i++)
{
sum1 += array[i][i];
}
//sum of right to left diaganol
for (int j = 0; j < array.length; j++)
{
sum2 += array[j][array.length-1-j];
}
if (sum1 != sum2)
return false;
//Sum of Rows
for (int row = 0; row < array.length; row++)
{
sumRow = 0;
for (int col = 0; col < array[row].length; col++)
sumRow += array[row][col];
if (sumRow != sum1)
return false;
}
//Sum of Col
for (int i = 0; i < array.length; i++)
{
sumCol = 0;
for (int j = 0; j < array.length; j++)
sumCol = array[j][i];
if (sumCol != sum1)
return false;
}
return true;
}
public String toString()
{
int n = array.length;
String lol = "";
for (int[] row : array)
{
for (int num : row)
{
String hi = String.format("%0"+(n*n+"").length()+"d",num);
lol += hi + " ";
}
lol += "\n";
}
return lol;
}
}
Here is my driver class
import javax.swing.*;
public class SquareMatrixDriver {
public static void main(String[] args) { //My favorite line in history
JFrame bot = new JFrame(); //We can use JFrame to read the inputs
do
{
//We have to make sure that it is a valid input or else I am doomed
int size = 0;
do
{
size = Integer.parseInt(JOptionPane.showInputDialog(bot, "Enter the size of the matrix."));
if (size < 1)
{
JOptionPane.showMessageDialog(bot, "Invalid size! Enter a number greater than 0.");
}
}
while(size < 1);
SquareMatrix matrix = new SquareMatrix(size);
for (int i=0; i<size; i++)
{
//Gets thhe User's Input
String[] stringInput;
do
{
stringInput = JOptionPane.showInputDialog(bot, "Enter the row number" + (i + 1) + ", with " + size + " elements, split by commas.").split(",");
if (stringInput.length != size)
{ //In this code we basically enter the numbers with commas
JOptionPane.showMessageDialog(bot, "Invalid size! " + stringInput.length + " elements entered but " + size + " required.");
}
}
while(stringInput.length != size);
int[] intInput = new int[size];
for (int o=0; o<size; o++)
{
}
for (int o=0; o<size; o++)
{
matrix.add(Integer.parseInt(stringInput[o]), i, o); //Here we would put everything into the Matrix
}
}
JOptionPane.showMessageDialog(bot, "The matrix is " + (matrix.isMagic()? "very" : "not") + " correct"); //This line will output if the Matrix works or doesnt work
JOptionPane.showMessageDialog(bot, matrix); // Enters out the final output
} while (JOptionPane.showConfirmDialog(bot, "Do you wish to exit?", "Exit", JOptionPane.YES_NO_OPTION) == 1); //Asks the User if they would like to exit the program
}
}
Errors that I could find by visual inspection:
allUnique() is completely wrong, you have to check if each number occurs only once in the matrix, but you are comparing row arrays that is something totally different, the best way to check unicity would be normally to use an hashset, but since here you have a very defined range of numbers (from 1 to n2), then use any array of n2 booleans. Scan the square matrix and test/set the corresponding element in the array, if already set return false.
public boolean allUnique() {
int n=array.length;
boolean[] set=new boolean[n*n];
for (int i=0; i < n; i++) {
for (int j=0;j < n; j++) {
//Here assuming that you already sucessfully called allInRange,
//otherwise we must check bounds to avoid an index out of bounds exception
if(set[array[i][j]-1]) {
return false;
}
set[array[i][j]-1] = true;
}
}
return true;
}
In method isMagic() all this part is wrong and redundant
boolean range = allInRange();
if (range == true)
return true; //WRONG, this will immediately return with true, without further checks
if (range == false)
return false;
boolean unique = allUnique();
if (unique == true)
return true; //WRONG, same as before
if (unique == false)
return false;
Just replace it with
if (!allInRange()) {
return false;
}
if (!allUnique()) {
return false;
}
Finally in isMagic() when you calculate the column's sum, the addition is missing
sumCol = array[j][i];
must be replaced with
sumCol += array[j][i];