Javascriptを、516 363 304 276 243 240のバイト
私の解決策は、スパイラルで密な行列を作成せず、代わりに、指定された順序のウラム行列の指定された数に対応するインデックスを返します。したがって、2からM * Mの間の数値を反復処理し、fn ulamIdxで指定されたidxを使用して素数の配列を作成します
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