def output_spiral(n)
#For formatting, determine the length of the largest number
max_number_length = n.to_s.length
#Determine matrix size
max_x = Math.sqrt(n).floor
max_y = Math.sqrt(n).floor
if max_x * max_y < n
max_x += 1
if max_x * max_y < n
max_y += 1
end
end
#The a matrix of the required size.
#Note that for simplicity in printing spiral is an array of row arrays.
spiral = Array.new
row = Array.new(max_x){ |i| ' ' }
max_y.times{ spiral << row.clone }
#Determine the starting point index (ie where to insert 1)
x = ((max_x-1)/2).floor
y = ((max_y-1)/2).floor
#Input the start point value, formatted to the right size
spiral[y][x] = "%0#{max_number_length}d" % 1
#Setup counters required to iterate through the spiral
steps_in_direction = 1 #This defines how many steps to take in a direction
steps_count = 0 #This defines how many steps have been taken in the direction
direction = 'right' #This defines the direction currently travelling
steps_in_direction_count = 0 #This define how many times we have used the same steps_in_direction value
#Iterate through all the numbers up to n
2.upto(n) do |i|
#Change index based on the direction we are travelling
case direction
when 'right' then x += 1
when 'down' then y += 1
when 'left' then x -= 1
when 'up' then y -= 1
end
#Input the value, formatted to the right size
spiral[y][x] = "%0#{max_number_length}d" % i
#Increment counters
steps_count += 1
if steps_count == steps_in_direction
steps_count = 0
steps_in_direction_count += 1
if steps_in_direction_count == 2
steps_in_direction += 1
steps_in_direction_count = 0
end
case direction
when 'right' then direction = 'down'
when 'down' then direction = 'left'
when 'left' then direction = 'up'
when 'up' then direction = 'right'
end
end
end
#Output spiral
spiral.each do |x|
puts x.join(' ')
end
end
output_spiral(95)