Javascript, 516 363 304 276 243 240 байт
Моє рішення не створює щільної матриці зі спіраллю, натомість повертає індекс, що відповідає заданому номеру в матриці Улама заданого порядку. Таким чином, воно перебирається через числа між 2 і M * M і створює масив простих чисел з idx, заданим 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);
Мінімізований виглядає так:
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);
Для входу 15 вихід:
,,,,,,,,,,,,,,,, 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