В рубине:
N=gets.to_i
index = -N
width = N
result = []
n = 0
dir=-1
while n < N*N
dir = (dir + 1) % 4
dir_x, dir_y = [[0,1],[1,0],[0,-1],[-1,0]][dir]
width -= 1 if [1,3].include?(dir)
1.upto(width) { |m|
n += 1
index += dir_y * N + dir_x
result[index] = n
}
end
width = (N*N).to_s.size
result.each_slice(N) { |l|
print l.map {|n| "%0#{width}d" % n }.join(" "), "\n"
}
Тестовое задание:
$ ruby1.9 769.rb <<< 9
01 32 31 30 29 28 27 26 25
02 33 56 55 54 53 52 51 24
03 34 57 72 71 70 69 50 23
04 35 58 73 80 79 68 49 22
05 36 59 74 81 78 67 48 21
06 37 60 75 76 77 66 47 20
07 38 61 62 63 64 65 46 19
08 39 40 41 42 43 44 45 18
09 10 11 12 13 14 15 16 17
Другое решение, использующее вычисления отсюда :
N=gets.to_i
r=[]
tr=->x,y{ x+(N-1)/2 + (y+(N-1)/2+(N-1)%2)*N }
r[tr[0,0]] = N*N
1.upto(N*N-1) { |n|
shell = ((Math.sqrt(n)+1)/2).to_i
leg = (n-(2*shell-1)**2)/(2*shell)
element = (n-(2*shell-1)**2)-2*shell*leg-shell+1
x,y = [[element,-shell],[shell,element],[-element,shell],[-shell,-element]][leg]
r[tr[x,y]] = N*N-n
}
r.each_slice(N) {|l|
puts l.map { |n|
"%0#{(N*N).to_s.size}d" % (n or 0)
}.join(" ")
}
Тестовое задание:
$ ruby1.9 769-2.rb <<< 5
01 16 15 14 13
02 17 24 23 12
03 18 25 22 11
04 19 20 21 10
05 06 07 08 09