function makeArray( s )
local q = {}
for j = 1, s do
table.insert( q, {} )
for i = 1, s do
table.insert( q[j], 0 )
end
end
return q
end
-- [[ odd magic square ]] --
function buildOMS( s )
if s % 2 == 0 then s = s + 1 end
local q, p = makeArray( s ), 1
local i, j, ti, tj = 1 + math.floor( s / 2 ), 1
while( p <= s * s ) do
q[i][j] = p
ti = i + 1; if ti > s then ti = 1 end
tj = j - 1; if tj < 1 then tj = s end
if q[ti][tj] ~= 0 then
ti = i; tj = j + 1
end
i = ti; j = tj; p = p + 1;
end
return q, s
end
-- [[ singly even magic square ]] --
function buildSEMS( s )
if s % 2 == 1 then s = s + 1 end
while( s % 4 == 0 ) do s = s + 2 end
local q, z, o = makeArray( s ), math.floor( s / 2 )
local b, c, d, a = z * z; c = 2 * b; d = 3 * b
o = buildOMS( z )
for j = 1, z do
for i = 1, z do
a = o[i][j]
q[i][j] = a
q[i + z][j + z] = a + b
q[i + z][j] = a + c
q[i][j + z] = a + d
end
end
local lc = math.floor( z / 2 )
local rc, t = lc - 1
for j = 1, z do
for i = 1, s do
if i <= lc or i > s - rc or ( i == lc + 1 and j == lc + 1 ) then
if not( i == 1 and j == lc+ 1 ) then
t = q[i][j]
q[i][j] = q[i][j + z]
q[i][j + z] = t
end
end
end
end
return q, s
end
-- [[ doubly even magic square ]] --
function buildDEMS( s )
while( s % 4 > 0 ) do s = s + 1 end
local q = makeArray( s )
local temp, n, tot, sx, sy = {{1,0,0,1}, {0,1,1,0}, {0,1,1,0}, {1,0,0,1}},
0, s * s
for j = 1, s do
for i = 1, s do
sx = i % 4; if sx < 1 then sx = 4 end
sy = j % 4; if sy < 1 then sy = 4 end
if temp[sy][sx] == 1 then q[i][j] = n + 1
else q[i][j] = tot - n end
n = n + 1
end
end
return q, s
end
function myFormat( s, l )
for i = 1, l - #s do
s = "0" .. s
end
return s .. " "
end
LOG_10 = 2.302585092994
function display( q, s )
io.write( string.format( " - %d x %d\n", s, s ) )
local k = 1 + math.floor( math.log( s * s ) / LOG_10 )
for j = 1, s do
for i = 1, s do
io.write( myFormat( string.format( "%d", q[i][j] ), k ) )
end
print()
end
io.write( string.format( "Magic sum: %d\n", s * ( ( s * s ) + 1 ) / 2 ) )
end
--[[ entry point ]]--
io.write( "\nOdd Magic Square" )
display( buildOMS( 9 ) )
io.write( "\nSingly Even Magic Square" )
display( buildSEMS( 6 ) )
io.write( "\nDoubly Even Magic Square" )
display( buildDEMS( 8 ) )