```On May 18, 6:57 pm, Ruby Quiz <j... / grayproductions.net> wrote:
> The three rules of Ruby Quiz:
>
> 1.  Please do not post any solutions or spoiler discussion for this quiz until
> 48 hours have passed from the time on this message.
>
> 2.  Support Ruby Quiz by submitting ideas as often as you can:
>
> http://www.rubyquiz.com/
>
> 3.  Enjoy!
>
> Suggestion:  A [QUIZ] in the subject of emails about the problem helps everyone
> if you can.
>
> -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
>
> A magic square of size N is a square with the numbers from 1 to N ** 2 arranged
> so that each row, column, and the two long diagonals have the same sum.  For
> example, a magic square for N = 5 could be:
>
>         +------------------------+
>         | 15 |  8 |  1 | 24 | 17 |
>         +------------------------+
>         | 16 | 14 |  7 |  5 | 23 |
>         +------------------------+
>         | 22 | 20 | 13 |  6 |  4 |
>         +------------------------+
>         |  3 | 21 | 19 | 12 | 10 |
>         +------------------------+
>         |  9 |  2 | 25 | 18 | 11 |
>         +------------------------+
>
> In this case the magic sum is 65.  All rows, columns, and both diagonals add up
> to that.
>
> This week's Ruby Quiz is to write a program that builds magic squares.  To keep
> the problem easy, I will say that your program only needs to work for odd values
> of N.  Try to keep your runtimes pretty reasonable even for the bigger values of
> N:
>
>         \$ time ruby magic_square.rb 9
>         +--------------------------------------------+
>         | 45 | 34 | 23 | 12 |  1 | 80 | 69 | 58 | 47 |
>         +--------------------------------------------+
>         | 46 | 44 | 33 | 22 | 11 |  9 | 79 | 68 | 57 |
>         +--------------------------------------------+
>         | 56 | 54 | 43 | 32 | 21 | 10 |  8 | 78 | 67 |
>         +--------------------------------------------+
>         | 66 | 55 | 53 | 42 | 31 | 20 | 18 |  7 | 77 |
>         +--------------------------------------------+
>         | 76 | 65 | 63 | 52 | 41 | 30 | 19 | 17 |  6 |
>         +--------------------------------------------+
>         |  5 | 75 | 64 | 62 | 51 | 40 | 29 | 27 | 16 |
>         +--------------------------------------------+
>         | 15 |  4 | 74 | 72 | 61 | 50 | 39 | 28 | 26 |
>         +--------------------------------------------+
>         | 25 | 14 |  3 | 73 | 71 | 60 | 49 | 38 | 36 |
>         +--------------------------------------------+
>         | 35 | 24 | 13 |  2 | 81 | 70 | 59 | 48 | 37 |
>         +--------------------------------------------+
>
>         real    0m0.012s
>         user    0m0.006s
>         sys     0m0.006s
>
> For extra credit, support even values of N.  You don't need to worry about N = 2
> though as it is impossible.

Here it is:
# magic_square.rb
# Magic Square with Odd Number
class OddMagicSquare

def initialize(n)
@square = Array.new(n)
@square.each_index {|i| @square[i] = Array.new(n)}
middle = n/2
@square[0][middle] = 1
@pos = [0,middle]
@len = n
end

def printing_magic_square
v_border = '+' + '-' * (6 * @len - 1) + '+'
@square.each do |row|
puts v_border
row.each do |r|
if r then
print format('|' + "%4d" + ' ', r)
else
print '| nil '
end
end
print "|\n"
end
puts v_border
end

def iterate_square
value = 2
last_value = @len ** 2
while true do
move
fill value
break if value == last_value
value = value + 1
end
end

private

def fill(value)
@square[@pos[0]][@pos[1]] = value
end

def move
move_down if not move_diagonal_up
end

def move_diagonal_up
# get future position
future_pos = Array.new(2)
@pos[0] == 0 ? future_pos[0] = @len - 1 : future_pos[0] = @pos[0]
- 1
@pos[1] == @len - 1 ? future_pos[1] = 0 : future_pos[1] = @pos[1]
+ 1
# check if it is empty or not
if @square[future_pos[0]][future_pos[1]] then
return false
else
@pos = future_pos
end
return true
end

def move_down
@pos[0] == @len - 1 ? @pos[0] = 0 : @pos[0] = @pos[0] + 1
end

end

The test case:
#tc_magic_square.rb
require 'test/unit'

require 'magic_square'

class TestOddMagicSquare < Test::Unit::TestCase

def setup
@n = 5
@odd_magic_square = OddMagicSquare.new(@n)
@odd_magic_square.iterate_square
@square = @odd_magic_square.square
@sum = (@n ** 2 / 2 + 1) * @n
end

def test_sum_row_and_col
@n.times do |t|
assert_equal @sum, get_sum_column(t)
assert_equal @sum, get_sum_row(t)
end
assert_equal @sum, get_sum_diagonal('left')
assert_equal @sum, get_sum_diagonal('right')
end

private

def get_sum_column(i)
sum = 0
@n.times do |t|
sum += @square[t][i]
end
sum
end

def get_sum_row(i)
sum = 0
@n.times do |t|
sum += @square[i][t]
end
sum
end

def get_sum_diagonal(alignment)
if alignment == 'left' then
sum = i = 0
@n.times do |t|
sum += @square[i][i]
i = i + 1
end
return sum
elsif alignment == 'right' then
sum = 0
i = @n - 1
@n.times do |t|
sum += @square[i][i]
i = i - 1
end
return sum
else
raise 'Alignment must be left or right.'
end
end

end

Here how it is run:
# use_magic_square.rb
require 'magic_square'

# getting input
n = ARGV[0].to_i

# input must be odd and bigger than 2
raise 'Argument must be odd and bigger than 2' if n % 2 == 0 or n < 3

odd_magic_square = OddMagicSquare.new(n)
odd_magic_square.iterate_square
odd_magic_square.printing_magic_square

\$ ruby use_magic_square.rb 5
+-----------------------------+
|  17 |  24 |   1 |   8 |  15 |
+-----------------------------+
|  23 |   5 |   7 |  14 |  16 |
+-----------------------------+
|   4 |   6 |  13 |  20 |  22 |
+-----------------------------+
|  10 |  12 |  19 |  21 |   3 |
+-----------------------------+
|  11 |  18 |  25 |   2 |   9 |
+-----------------------------+

```