PG915
PG915

Reputation: 1

Is there something wrong with my Magic Square Code?

A brief explanation: With the code below it will make a randomly generated Square and some code below would make sure that it was a Magic Square, in which the sum of the elements in each row, column, and the two diagonals are the same value. My teacher said at maximum it should take three minutes to generate a magic square. So all I ask is there anything that can be done to improve or fix this code, please?

import java.util.ArrayList;
import java.util.Random;

class Main {
    public static void main(String[] args) {
        int size = 9;
        int N = 3;
        boolean result = true;
        ArrayList<Integer> list = new ArrayList<Integer>(size);
        int[][] mat = new int[N][N];

        while (result) {    
            for (int i = 1; i <= size; i++) {
                list.add(i);
            }
      
            Random rand = new Random();

            for (int i = 0; i < N; i++) {
                for (int j = 0; j < N; j++) {
                    int index = rand.nextInt(list.size());
                    System.out.print(list.remove(index)+" ");
                }

                System.out.println();
            }
      
            System.out.println();
            // Checking process  
            // sumd1 and sumd2 are the sum of the two diagonals
            int sumd1 = 0, sumd2 = 0;

            for (int i = 0; i < N; i++) {
                // (i, i) is the diagonal from top-left -> bottom-right
                // (i, N - i - 1) is the diagonal from top-right -> bottom-left
                sumd1 += mat[i][i];
                sumd2 += mat[i][N - 1 - i];
            }

            // if the two diagonal sums are unequal then it is not a magic square
            if (sumd1 != sumd2)
                result = false;
 
            // calculating sums of Rows and columns and checking if they are equal to each other,as well as equal to diagonal sum or not
            for (int i = 0; i < N; i++) {
                int rowSum = 0, colSum = 0;
            
                for (int j = 0; j < N; j++) {
                    rowSum += mat[i][j];
                    colSum += mat[j][i];
                }

                if (rowSum != colSum || colSum != sumd1)
                    result=false;
            }

            result = true; 
        }
    }
}

Upvotes: 0

Views: 230

Answers (1)

Joop Eggen
Joop Eggen

Reputation: 109557

Trying with random numbers to coincidentally find a solution is deadly slow.

If you have the numbers 1 to 9, its entire sum 1+2+3+...+8+9 is 9*(1+9)/2 = 45. As you have 3 rows and 3 colums, a row and column must sum upto 45/3 = 15.

Now that should restrict the number of possibilities.

So you must build in some intelligence in the code. Avoid random numbers as they do not even guarantee you'll find a solution in hundred years.

If you already treated recursion, that would be the easiest way to try all possibly valid combinations.

If you already treated Set, a BitSet maybe might be useful for a row, column or diagonal.

If you find it hard to code walking through all possibilities, you might hold the 2 dimensional matrix in a 1 dimensional array int[N*N], and have N (rows) + N (columns) + 2 (diagonals) arrays of N indices.

And of course I will not spoil your fun and satisfaction finding a smart solution.

Work it out on paper first.

Upvotes: 1

Related Questions