A magic square with odd-sized sides
A magic square in size – this is a matrix filled with integers from 1 to so that the sum of the numbers along each row, each column, and the main diagonals are the same and equal .
The algorithm for solving the problem
Siamese method filling a magic square of the size (where an odd number) It consists of the following steps:
- Select a cell in the middle of the top row, accept
- Place in the selected cell
- If This means that the square is filled in and you can exit the procedure. Otherwise, increase per unit
- Move to the cell above and to the right of the current one. Go to the first column or the last row when leaving the matrix. If the new cell is already filled with a non-zero number, go back and instead move 1 cell lower (vertically).
- Go back to step 2
Pkg.add(["Colors", "LinearAlgebra"])
N = 7
magic_square = Matrix{Int}(zeros(N,N))
n = 1
i = 1
j = N ÷ 2
while n <= N^2
magic_square[i, j] = n
n += 1
newi, newj = mod1((i-1), N), mod1((j+1), N)
if magic_square[newi, newj] > 0
i = mod1( i+1, N )
else
i, j = newi, newj
end
end
display( magic_square )
gr()
heatmap( magic_square, c=:Greens, size=(200,200), cbar=:false,
xticks=false, yticks=false )
# Вычислим координаты, текст и цвет надписей
vec_coords = CartesianIndices( size(magic_square) )
ax = first.( Tuple.(vec_coords[:]) )
ay = last.( Tuple.(vec_coords[:]) )
az = reshape( magic_square, 1, : )
acol = [ n > (N^2)÷2 ? (:white) : (:black) for n in az ]
# Нанесем на график надписи
for (x,y,z,c) in zip(ax,ay,az,acol)
annotate!( x, y, text("$(convert(Int64, round(z)))",9,"Helvetica",c) );
end
plot!()
Let's check that we got exactly the magic square. Here is the sum for all columns:
sum.( eachcol( magic_square ) )
The sum of all lines:
sum.( eachrow( magic_square ) )
The sum of the numbers on the main diagonal:
using LinearAlgebra
sum( diag( magic_square) )
The sum of the numbers on the side diagonal:
sum( diag( magic_square') )
Let's check all the conditions at once:
using Colors
verdict = all( vcat( sum.( eachcol( magic_square ) ),
sum.( eachrow( magic_square ) ),
sum( diag( magic_square) ),
sum( diag( magic_square') ) ) .== N*(N^2 + 1) ÷ 2 )
if verdict == true display( colorant"green" ) else display( colorant"red" ); end;
If we set an even value these conditions will not be satisfied (the result will be false).
Conclusion
We have implemented a procedure for constructing a magic square with some limitations. It embodies a fairly simple algorithm, and studying it is definitely useful for developing intuition in the field of programming.