Javascript, 516 363 304 276 243 240 Bytes
Mi solución no crea una matriz densa con la espiral, sino que devuelve el índice que corresponde al número dado en la matriz de Ulam del orden dado. Por lo tanto, itera a través de los números entre 2 y M * M y crea una matriz de primos con el idx dado por el fn ulamIdx
M=15;
$=Math;
_=$.sqrt;
/**
* Return M*i+j (i.e. lineal or vector idx for the matrix) of the Ulam Matrix for the given integer
*
* Each Segment (there are 4 in each round) contains a line of consecutive integers that wraps the
* inner Spiral round. In the foCowing example Segments are: {2,3}, {4,5},
* {6,7}, {8,9}, {a,b,c,d}, {e,f,g,h}, {i,j,k,l}, {m,n,o,p}
*
* h g f e d
* i 5 4 3 c
* j 6 1 2 b
* k 7 8 9 a
* l m n o p
*
* @param n integer The integer which position in the Matrix we want.
* @param M integer Matrix Order.
*/
/*
* m: modulus representing step in segment in current spirtal round
* v: Step in current spiral round, i.e. n - (inner spirals greatest num.)
* s: the current Segment one of [1, 2, 3, 4] that represents the current spiral round
* L: Segment Length (Current spiral round Order - 1)
* B: inner Spiral Order, for trib¿vial case 1 it's -1 special case handled differently.
* C: relative line (row or column) corresponding to n in current spiral Round
* R: relative line (column or row) corresponding to n in current spiral Round
* N: Curren (the one that contains n) Spiral (matrix) round Order
* D: Difference between M and the current Spiral round order.
*/
/**
* Runs the loop for every integer between 2 and M*M
* Does not check sanity for M, that should be odd.
*/
r=[];
for (x = 2; x < M * M; x++) {
p=1;
// Is Prime?
for (k = 2; p&&k <= _(x); k++)
if (x % k==0) p=0;
if (p) {
B = $.floor(_(x - 1));
B=B&1?B:B-1;
N = B + 2;
D = (M - N) / 2;
v = x - B * B;
L = B + 1;
s = $.ceil(v / L);
m = v % L || L;
C = D + (s < 3 ? N - m : 1 + m);
R = s&2 ? D + 1 : D + N;
w= s&1 ? M * C + R : M * R + C;
// /*uncomment to debug*/ console.log("X:" + x + ": " + ((s&1) ? [C, R].join() : [R, C].join()));
r[w] = x;
}
}
alert(r);
Minified se ve así:
for(M=15,$=Math,_=$.sqrt,r=[],x=2;x<M*M;x++){for(p=1,k=2;p&&k<=_(x);k++)x%k==0&&(p=0);p&&(B=$.floor(_(x-1)),B=1&B?B:B-1,N=B+2,D=(M-N)/2,v=x-B*B,L=B+1,s=$.ceil(v/L),m=v%L||L,C=D+(s<3?N-m:1+m),R=2&s?D+1:D+N,w=1&s?M*C+R:M*R+C,r[w]=x)}alert(r);
Para la entrada 15, la salida es:
,,,,,,,,,,,,,,,, 197 ,,,, 193`` 191 ,,,,,,,,,,,,,,,, 139 ,, 137 ,,,,, 199, 101 ,,,, 97 ,,,,,,,, 181 ,,,,,,,, 61,, 59 ,,,, 131 ,,,, 103,, 37 ,,,,,, 31, 89, 179, 149, 67, 17 ,,,, 13 ,,,,,,,,,,,, 5, 3, 29 ,,,,,, 151 ,,, , 19 ,,, 2,11,, 53,, 127 ,,, 107,, 41,, 7 ,,,,,,,,,,,, 71 ,,,, 23 ,,,,,,, ,,, 109 ,, 43 ,,,, 47 ,,,, 83 ,, 173 ,,,, 73 ,,,,,, 79 ,,,,,,,,,, 113 ,,,,,,, ,,,,, 157 ,,,,,, 163 ,,,, 167 ,,,, 211 ,,,,,,,,,,,, 223