C #, 203 202 196 193 178 ไบต์
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;}
บันทึกเป็นไบต์ด้วย @StefanDelport
บันทึกแล้ว 22 ไบต์ขอบคุณ @FelipeNardiBatista
สิ่งนี้ทำงานโดยการสังเกตต่อไปนี้เกี่ยวกับวิธีการสร้างกำลังสอง:

ในขณะที่คุณสามารถเห็นแต่ละบิตจะถูกเพิ่มลงในตารางก่อนหน้า สำหรับเลขคู่ที่เราไปทางขวาของที่เราอยู่จนถึงจนถึงต่ำกว่าที่หนึ่งของตารางและจากนั้นไปทางซ้าย ตัวเลขที่แปลกเป็นสิ่งที่ตรงกันข้ามเราไปทางซ้ายหนึ่งจนถึงสูงกว่าความสูงในปัจจุบันและจากนั้นไปจนจบ
เวอร์ชันเต็ม / ฟอร์แมต:
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
? หรือเลขคู่ใด ๆ