Ahh, this reminds me of college.  Some other people may have had to
look up the algorithm or figure it out by the supplied magic squares,
but a decade later, I still remember.  Of course, back then we started
at the bottom middle, not the top middle.  Doesn't make much of a
difference in the end, though, and that's why it's for odd side
lengths.



#!/usr/bin/env ruby

class MagicSquare
  Coords = Struct.new(:x, :y)

	def initialize(size)
	  @size = size.to_i
	  @final_num = @size**2
	  @coords = Coords.new(@size/2, 0)

    create_square
	end

	def init_square
	 @square = []
	 1.upto(@size) do
	   @square << [0] * @size
   end
	end

	def create_square
	  init_square

	  n = 1
	  while n <= @final_num
	    @square[@coords.y][@coords.x] = n
	    n += 1
	    next_coords
    end
  end

	def to_s
	  output = []
	  num_length = @final_num.to_s.length
	  num_length+2 * @size
	  hline = '+' + Array.new(@size, '-' * (num_length + 2)).join('+') +
'+'

	  output.push(hline)
	  (0...@size).each do |x|
	    output.push('| ' + @square[x].collect { |n|
sprintf("%#{num_length}d", n) }.join(' | ') + ' |')
	    output.push(hline)
    end
    output.join("\n")
  end

  private
  def next_coords
    new_coords = Coords.new((@coords.x-1 + @size) % @size,
(@coords.y-1 + @size) % @size)
    if @square[new_coords.y][new_coords.x] != 0
      new_coords = Coords.new(@coords.x, (@coords.y+1) % @size)
    end
    @coords = new_coords
  end
end


square = MagicSquare.new(ARGV[0])

puts square