My answers assumes an odd numbered spirals (I inferred it from "The 
number zero represents the center of the spiral").

Sorry for my beginners ruby (are there some standard min(x,y)/max(x,y,) 
functions?)

The approach is to work out a standard equation for the value in any 
cell (I ended up with two, for the top left and bottom right) and then 
to iterate through each cell and calculate the value.  The algorithm is 
stateless.

class SpiralMaker
  def make_spiral(size)
    # only allow odd numbered squares (as zero is centre)
    if (size.modulo(2) == 0)
      exit(1)
    end
   
    #step along row
    (1..size).each do |y|
      # step down columns
      (1..size).each do |x|
        # are we in top left or bottom right half of spiral?       
        if (y+x <= size) 
          # top left - calculate value
          sn = size - (2 * (min(x,y) - 1))
          val = (sn*sn) - (3*sn) + 2 - y + x
        else  
          # bottom right - calculate value     
          sn = size - (2 * (size - max(x,y)))
          val = (sn*sn) - sn + y - x
        end
        # Print value
        STDOUT.printf "%03d ", val
      end
      # Next line
      STDOUT.print "\n"
    end
  end
 
  def min(a,b)
    (a <= b) ? a : b
  end
 
  def max(a,b)
    (a >= b) ? a : b
  end
end

maker = SpiralMaker.new
maker.make_spiral 21