C #, 203 202 196 193 178 byte
n=>{var r=new int[n,n];for(int o=n-2+n%2>>1,i=r[o,o]=1,c=2,w=o,h=o,b=1-2*(i%2),j;n>i++;){r[h,w+=b]=c++;for(j=0;j<i-1;++j)r[h+=b,w]=c++;for(j=0;j<i-1;++j)r[h,w-=b]=c++;}return r;}
Đã lưu một byte nhờ @StefanDelport.
Đã lưu 22 byte nhờ @FelipeNardiBatista.
Điều này hoạt động bằng cách quan sát sau đây về cách các hình vuông được xây dựng:
Như bạn có thể thấy mỗi bit được thêm vào hình vuông trước đó. Đối với các số chẵn, chúng ta đi bên phải nơi chúng ta ở, xuống cho đến khi thấp hơn một ô so với vị trí của hình vuông và sau đó rời khỏi đến cuối. Các số lẻ về cơ bản là ngược lại, chúng ta đi bên trái một, cho đến khi một trên các chiều cao hiện tại và sau đó phải đến cuối.
Phiên bản đầy đủ / được định dạng:
using System;
using System.Linq;
class P
{
static void Main()
{
Func<int, int[,]> f = n =>
{
var r = new int[n, n];
for (int o = n - 2 + n % 2 >> 1, i = r[o, o] = 1, c = 2, w = o, h = o, b = 1 - 2 * (i % 2), j; n > i++;)
{
r[h, w += b] = c++;
for (j = 0; j < i - 1; ++j)
r[h += b, w] = c++;
for (j = 0; j < i - 1; ++j)
r[h, w -= b] = c++;
}
return r;
};
Console.WriteLine(String.Join("\n", f(3).ToJagged().Select(line => String.Join(" ", line.Select(l => (l + "").PadLeft(2))))) + "\n");
Console.WriteLine(String.Join("\n", f(4).ToJagged().Select(line => String.Join(" ", line.Select(l => (l + "").PadLeft(2))))) + "\n");
Console.WriteLine(String.Join("\n", f(5).ToJagged().Select(line => String.Join(" ", line.Select(l => (l + "").PadLeft(2))))) + "\n");
Console.ReadLine();
}
}
public static class ArrayExtensions
{
public static T[][] ToJagged<T>(this T[,] value)
{
T[][] result = new T[value.GetLength(0)][];
for (int i = 0; i < value.GetLength(0); ++i)
result[i] = new T[value.GetLength(1)];
for (int i = 0; i < value.GetLength(0); ++i)
for (int j = 0; j < value.GetLength(1); ++j)
result[i][j] = value[i, j];
return result;
}
}
4
? Hoặc bất kỳ số chẵn.