Javascript, 516 363 304 276 243 240 bytes
Minha solução não cria uma matriz densa com a espiral, mas retorna o índice que corresponde ao número especificado na matriz de Ulam da ordem dada. Então, ele percorre os números entre 2 e M * M e cria uma matriz de números primos com o idx fornecido pelo 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 parece com isso:
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 a entrada 15, a saída é:
,,,,,,,,,,,,,,,, 197 ,,,, 193,, 191 ,,,,,,,,,,,,,,, 139, 137 , 199,, 101 ,,,, 97 ,,,,,,,, 181 ,,,,,,, 61, 59 ,,,, 131 ,, 103, 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, 79, 79, 113, 113 ,,,,,, 113 ,,,,,,, ,,,,, 157 ,,,,,, 163 ,,,, 167 ,,,, 211 ,,,,,,,,,,,, 223