The magic square, is a matrix with a constant sum in every row, column, diagonal, which is known as magic sum. Each element in the magic square cannot be the same.
Here is a JavaScript solution when size of the sides of square is an odd number.
Rules:
- Put 1 in the middle of the first row of the matrix.
- Place the numbers in the matrix in ascending order along the upper left corner.
- If it is out of bounds, assume that there is a matrix around, put the number in that position.
- If position is already occupied, skip the position and put it below, then re-place it as usual.
function magicSquare(n) {
//create an empty array for writing numbers into it and store it in a variable `matrix`
let matrix = [];
//create a variable for the horizontal position - `x`
let x = 0;
//create a variable for the vertical position- `y`
let y = (n - 1) / 2;
//loop to iterate over strings (to create empty arrays equal to the size of the square)
for (let i = 0; i < n; i++) {
matrix[i] = [];
//loop to iterate over columns (to create cells with null values in a previously created arrays)
for (let j = 0; j < n; j++) {
matrix[i][j] = 0;
}
}
//filling arrays with numbers - the number of iterations is equal to the square of the matrix size
for (let i = 0; i < n * n; i++) {
pos(i + 1);
}
//function with filling rules which has as argument `value` equal to the square of the matrix size
function pos(value) {
//filling in the cell corresponding to the calculated values of `x` and` y`
matrix[x][y] = value;
//create variables to store the current values of `x` and` y` or the current positions of the number
let tx = x;
let ty = y;
//decrease the value of `x` by 1
x--;
//if the value of `x` is less than zero, then add to the `x` variable a number equal to the size of the matrix
if (x < 0) {
x += n;
}
//the same for `y` variable
y--;
if (y < 0) {
y += n;
}
//if the number in the cell is not 0
if (matrix[x][y] !== 0) {
//then 1 is added to `tx` variable and stored in the `x` variable
x = tx + 1;
//if `x` variable is equal to the size of the matrix
if (x === n) {
//then x equals 0
x = 0;
}
//`y` equals the value` ty`, i.e. last number "address"
y = ty;
}
}
//after loop of filling the numbers, the filled "matrix" is returned
return matrix;
}
Check given matrix is magic square or not:
function isMagicSquare(mat) {
let N = mat.length;
// `sumd1` and` sumd2` - the sum of the number along the diagonals
let sumd1 = 0,
sumd2 = 0;
for (let i = 0; i < N; i++) {
// (i, i) - diagonal from top left corner to bottom right
// (i, N - i - 1) - diagonal from top right to bottom left
sumd1 = sumd1 + mat[i][i];
sumd2 = sumd2 + mat[i][N - 1 - i];
}
// if the two diagonal sums are not equal, then this is not a magic square
if (sumd1 != sumd2) return false;
//similar check for rows and columns
for (let i = 0; i < N; i++) {
let colSum = 0;
let rowSum = 0;
for (let j = 0; j < N; j++) {
rowSum += mat[i][j];
colSum += mat[j][i];
}
if (rowSum != colSum || colSum != sumd1) return false;
}
return true;
}
For size of the sides of square equals 3:
let oddNumber = 3;
console.log(magicSquare(oddNumber));
console.log(isMagicSquare(magicSquare(oddNumber)));
Output:
[ [ 6, 1, 8 ],
[ 7, 5, 3 ],
[ 2, 9, 4 ] ]
true