ウラムのらせんの素数


17

Ulamのスパイラルは、数学では本当に魅力的でありながら不可解なトピックです。詳細については、こちらをご覧ください。ただし、短い要約は次のように説明できます。

最初に1を書くことから始め、次にその右側に2を書きます。2つの上に3を書き、その左側に4を書きます。このパターンを1(および私と1の間の数字)を無限に(または停止するように指示されるまで)旋回させ、らせんパターンを形成します。(下の例を参照)

目的

行の数と相関する入力としてn(常にゼロより大きい奇数)を受け入れるプログラムを作成し、Ulamスパイラルの行ごとに素数の値を出力します。書式設定はどのような方法でもかまいませんが、人間が判読できる明白なものでなければなりません

たとえば、入力3を指定する5,3,2,7と、3行が次の螺旋を生成するため、プログラムはを出力する必要があります。

5 4 3 <-- first row has the primes 5 and 3
6 1 2 <-- second row has the prime 2
7 8 9 <-- third row has the prime 7

これはコードゴルフであるため、バイト数が最も少ない答えが(どれだけ非効率であっても)勝ちます!標準的な抜け穴は受け入れられません。


末尾のコンマは許可されますか?または、スペースを区切って、たとえば「 `` 5 3 2 7```」
トムカーペンター

5
人間が読むことができ、素数を教えてくれる限り、お気軽に。
アディソンクランプ

回答:


8

Pyth、20バイト

f}TPTsuC+R=hZ_GtyQ]]

オンラインで試す:デモンストレーション

このコードは、完全にUlamのスパイラルを生成し、素数のすべてのラインとフィルターを接続します。

説明:

f}TPTsuC+R=hZ_GtyQ]]   implicit: Z = 0
      u           ]]   reduce, start with G = [[]]
               tyQ     for H in [0, 1, ..., 2*input-2] do:
             _G           reverse the order of the lines
        +R=hZ             append Z + 1 at the end of each line, 
                          updating Z each time with the new value Z + 1
       C                  update G with the transposed of ^
                       this gives the Ulam's spiral
     s                 combine all lines to a big list of numbers
f                      filter for numbers T, which satisfy:
 }TPT                    T appears in the prime-factorization of T
                         (<==> T is prime)

6

MATLAB、48

a=fliplr(spiral(input(''))');disp(a(isprime(a)))

基本的に、これは必要なサイズのスパイラル(ユーザーから要求された)を作成し、正しい行の順序で表示されるように配置します。これはaに保存されます。次に、素数であるのすべての値を表示します。

読み取り可能な形式を言ったように、1バイトを保存し、disp()のデフォルト出力(テストケースではn = 3)に進みました。

 5
 3
 2
 7

追加のボーナスとして、これは偶数を含むn> 0に対して機能します。たとえば、n = 10の出力は次のとおりです。

97
61
59
37
31
89
67
17
13
 5
 3
29
19
 2
11
53
41
 7
71
23
43
47
83
73
79

1
非常に素晴らしい!そのspiral機能を知っていること
ルイスメンドー

6

CJam、42 33バイト

Xali(2*{_W%zY@,Y+:Y,>a+}*e_{mp},`

オンラインで試す

最新バージョンには、@ Martinが提案する大幅な改善が含まれています。

スパイラルを構築する方法は、各ステップで、これまでのマトリックスを90度回転し、行に追加の番号を追加することです。これは何(n / 2) * 4度も繰り返されます。

次に、結果の行列の値は、素数であるためにフィルタリングされます。

説明:

Xa    Push initial matrix [1].
li    Get input and convert to int.
(2*   Calculate 2*(n-1), which is the number of rotations and row additions needed.
{     Start rotation loop.
  _     Copy current matrix for getting number of rows later.
  W%    Reverse the order of the rows...
  z     ... and transpose the matrix. The combination produces a 90 degree rotation.
  Y     Get next value from variable Y (which is default initialized to 2).
  @,    Rotate previous matrix to top, and get number of rows. This is the number
        of columns after the 90 degree rotation, meaning that it's the length of
        the row to be added.
  Y+    Add first value to row length to get end value.
  :Y    Save it in Y. This will be the first value for next added row.
  ,     Create list of values up to end value.
  >     Slice off values up to start value, leaving only the new values to be added.
  a+    Wrap the new row and add it to matrix.
}*    End of rotation loop.
e_    Flatten matrix into list.
{mp}, Filter list for primes.
`     Convert list to string for output.

2/4*に置き換えることができます2*か、またはそのように意図的に残しましたか?
-ETHproductions

@ETHproductionsこれは整数除算であるため、同等ではありません。たとえば、入力3の場合、結果は4である必要があります。実際、今考えてみると、保存すべきバイトがあると思います。(2*正しいはずです。
レトコラディ

5

Mathematica 223

これは、クラムのウラムスパイラルのコードに適しています。それが私がコミュニティwikiとしてそれを提出している理由です。私は単にそれをゴルフし、それらが存在する行によってリストされている素数を選択しました。

r=Range;i=Insert;t=Transpose;s@n_:=#~Select~PrimeQ&/@Nest[With[{d=Length@#,l=#[[-1,-1]]},
Composition[i[#,l+3d+2+r[d+2],-1]&,t@i[t@#,l+2d+1+r[d+1],1]&,i[#,l+d+r[d+1,1,-1],1]&,
t@i[t@#,l+r[d,1,-1],-1] &][#,15]]&,{{1}},(n-1)/2]

 s{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}}

表示を改善するには:

 %// MatrixForm

マトリックス


4

Mathematica、118バイト

f=Permute[Range[#*#],Accumulate@Take[Join[{#*#+1}/2,Flatten@Table[(-1)^j i,{j,#},{i,{-1,#}},{j}]],#*#]]~Select~PrimeQ&

これにより、後続の各番号の位置を次のように累積できることに注意して、線形形式でUlamスパイラルが生成されます。

{(n*n + 1)/2, +1, -n, -1, -1, +n, +n, +1, +1, +1, -n, -n, -n, ...}

すなわち、中央から始めて、右に1、上に1、左に2、下に2、右に3、上に3、...を移動します。

出力:

In[515]:= f[5]
Out[515]= {17,13,5,3,19,2,11,7,23}

1

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


それはかなりの圧縮でした。元のコードと変更点を説明できますか?
アディソンクランプ

役に立たないブラケットをいくつか削除しました。そして、uI()には同様のブロックを持つ4つの条件があります。それぞれが現在のセグメントの行と列を生成した3行(メインdocblockを参照)で4つのブロックをll&llt行に置き換え、戻り行がlltが行か列かを決定します。S&2は、(3,2)(上部および左セグメント)のsに当てはまります。s <3(sは(1,2)の右上にあります)。(1,3)のsのS&1は、ll&lltの値がrow&colまたはcol&rowおよびM(螺旋順)×row + colであるかどうかを決定します(修正行列のように、間違った線形idxで、正しさはll-1が必要
juanmf

メインループ(run())でiが素数(fnは<2も%1もテストする必要がないために削減された)の場合のみ、スパイラルのiのインデックス(ll、llt)を求めます。次に、結果の配列を出力します。
juanmf

概念的に重要な3つのマトリックスがあります。インナー、カレット、M。絶対的な行と列の計算に役立ちます。innerをnに減算すると、現在の(nが入る)螺旋状の相対intがussに残ります。そして、Mの順序と現在の順序の差分は、現在のラウンドの行と列のオフセットとして再生され、絶対値を取得します。
juanmf

364-> 240インラインでfnロジックを記述し、未使用のテストを削除します。
juanmf
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.