On May 18, 6:57 am, Ruby Quiz <j... / grayproductions.net> wrote:
> The three rules of Ruby Quiz:

A little late, but did it.
As always, enjoyed it vey much. Here is my solution

===============================
===============================

#! /usr/bin/ruby

# Ruby quiz 124 - Magic Squares
# Author: Ruben Medellin

class Array
  def sum
    inject(0){|a,v|a+=v}
  end
end

class MagicSquare

	attr_accessor :grid
	SHAPES = {:L => [3, 0, 1, 2], :U => [0, 3, 1, 2], :X => [0, 3, 2, 1]}

	# Validates the size, and then fills the grid
	# according to its size.
	# For reference, see
	# Weisstein, Eric W. "Magic Square." From MathWorld--A Wolfram Web
Resource.
	# http://mathworld.wolfram.com/	MagicSquare.html
	def initialize(n)
		raise ArgumentError if n < 3
		@grid = Array.new(n){ Array.new(n) }
		if n % 2 != 0
			initialize_odd(n)
		else
			if n % 4 == 0
				initialize_double_even(n)
			else
				initialize_single_even(n)
			end
		end
	end

	def [](x, y)
		@grid[x][y]
	end

	def display
		n = @grid.size
		space = (n**2).to_s.length
		sep = '+' + ("-" * (space+2) + "+") * n
		@grid.each do |row|
			print sep, "\n|"
			row.each{|number| print " " + ("%#{space}d" % number) + " |"}
			print "\n"
		end
		print sep, "\n"
	end

	def is_magic?
		n = @grid.size
		magic_number = (n * (n**2 + 1)) / 2
		for i in 0...n
			return false if @grid[i].sum != magic_number
			return false if @grid.map{|e| e[i]}.sum != magic_number
		end
		return true
	end

	private

	# Fill by crossing method
	def initialize_double_even(n)
		current = 1
		max = n**2
		for x in 0...n
			for y in 0...n
				if is_diag(x) == is_diag(y)
					@grid[x][y] = current
				else
					@grid[x][y] = max - current + 1
				end
				current += 1
			end
		end
	end

	def is_diag(n)
		n % 4 == 0 || n % 4 == 3
	end

	# Fill by LUX method
	def initialize_single_even(n)
		# Build an odd magic square and fill the new one based on it
		# according to the LUX method
		square = MagicSquare.new(n/2)
		m = (n+2)/4
		for x in 0...(n/2)
			for y in 0...(n/2)
				if(x < m)
					shape = (x == m-1 and x == y) ? :U : :L
					fill(x, y, square[x,y], shape)
				elsif ( x == m )
					shape = (x == y+1) ? :L : :U
					fill(x, y, square[x,y], shape)
				else
					fill(x, y, square[x,y], :X)
				end
			end
		end
	end

	def fill(x, y, number, shape)
		number = ((number-1) * 4) + 1
		numbers = [* number...(number + 4)]
		@grid[x*2][y*2] = numbers[ SHAPES[shape][0] ]
		@grid[x*2][y*2+1] = numbers[ SHAPES[shape][1] ]
		@grid[x*2+1][y*2] = numbers[ SHAPES[shape][2] ]
		@grid[x*2+1][y*2+1] = numbers[ SHAPES[shape][3] ]
	end

	# Fill by Kraitchik method
	def initialize_odd(n)
		x, y = 0, n/2
		for i in 1..(n**2)
			@grid[x][y] = i
			x = (x-1)%n
			y = (y+1)%n
			# If the new square is not empty, return to the inmediate empty
			# square below the former.
			unless @grid[x][y].nil?
				x = (x+2)%n
				y = (y-1)%n
			end
		end
	end

end

$stdout = File.new('magic_square', 'w') if ARGV.delete("-f")

$m = MagicSquare.new(ARGV[0] && ARGV[0].to_i || 5)
$m.display

if $DEBUG
	require 'test/unit'
	class SquareTest < Test::Unit::TestCase
		def test_magic
			assert($m.is_magic?)
		end
	end
end

$stdout.close

==============================
==============================

Thanks for the quizes.
Ruben.