울람의 나선의 소수


17

울람의 나선은 수학에서 진정으로 매력적이지만, 수수께끼의 주제입니다. 자세한 작동 방식은 여기 에서 확인할 수 있지만 간단한 요약은 다음과 같이 설명 할 수 있습니다.

나는 하나를 작성하여 시작한 다음 오른쪽에 두 개를 씁니다. 이 둘 위에 세 개를 쓰고 그 왼쪽에 네 개를 씁니다. 나는 1 (그리고 나와 1 사이의 숫자)을 무한대로 (또는 멈추라 고 할 때까지) 돌고있는이 패턴을 계속해서 나선형 패턴을 형성합니다. (아래 예 참조)

목표

행 수와 상관되는 입력으로 n (항상 0보다 큰 홀수 일 것) 을 허용하는 프로그램을 만든 다음 행의 소수 값을 Ulam 나선형 행으로 인쇄합니다. 형식은 어떤 방식이든 가능 하지만 사람이 읽을 수 있고 명확 해야합니다 .

예를 들어, 입력 3이 주어지면 5,3,2,73 개의 행이 다음과 같은 나선을 생성하기 때문에 프로그램이 출력해야합니다 .

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` ''
Tom Carpenter

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에 저장됩니다. 다음으로 소수의 모든 값을 표시합니다.

읽을 수있는 형식을 말했듯이 바이트를 저장하고 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*정확해야합니다.
Reto Koradi

5

매스 매 티카 223

이것은 Ulam 나선에 대한 Kuba의 코드에 적합합니다. 이것이 제가 커뮤니티 위키로 제출하는 이유입니다. 나는 단지 골프를 쳤고 프라임을 선택했다.

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&

이렇게하면 각 후속 번호의 위치가 다음과 같이 누적 될 수 있음을 알 수 있습니다.

{(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

자바 스크립트, 516 363 304 276 243 240 바이트

내 솔루션은 나선형으로 밀도가 높은 행렬을 만들지 않고 주어진 순서의 Ulam 매트릭스에 주어진 숫자에 해당하는 인덱스를 반환합니다. 따라서 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 ,,,,,,,,,,,,,,,,,,,,,,,, , 199,, 101 ,,,, 97 ,,,,,,,,, 181 ,,,,,,,,, 61,, 59 ,,,,, 131, 31,, 89,, 179,, 149,, 67,, 17 ,,,,, 13 ,,,,,,,,,,,,, 5,, 3,, 29 ,,,, , 19 ,,, 2,11,, 53,, 127 ,,,, 107,, 41,, 7 ,,,,,,,,,,,,, 71 ,,,,, 23, ,,, 109,, 43 ,,,,, 47 ,,,, 83,, 173 ,,,, 73 ,,,,,,,, 79 ,,,,,,,, ,,,,,, 157,``,,,,,, 163,``,, 167,``,,


그것은 약간의 압축이었습니다. 원래 코드와 변경 사항을 설명 할 수 있습니까?
애디슨 크럼

쓸모없는 괄호를 제거했습니다. 그리고 uI ()에는 비슷한 블록을 가진 4 개의 조건이 있다는 것을 깨달았습니다. 각각 현재 세그먼트에 대해 행과 열을 생성하는 3 줄이 있으므로 (주 문서 블록 참조) 4 개의 블록을 ll & llt 줄로 바꾸고 반환 줄은 llt가 행 또는 열인지 결정합니다. S & 2는 (3,2)의 s에 해당합니다 (상단 및 왼쪽 세그먼트). s <3, (1,2) 오른쪽 및 위의 s S & 1은 (1,3)에서 s & llt의 값이 row & col 또는 col & row이고 M (나선 순서) × row + col이 겹치는 색인을 방지하는지 여부를 결정합니다 (정류 행렬과 같지만 선형 IDX가 잘못됨) ll-1 필요
juanmf

메인 루프 (run ())에서 i가 소수 (fn은 <2 또는 % 1 테스트 할 필요가 없으므로 감소 함) 인 경우에만 나선형으로 i의 인덱스 (ll, llt)를 요청합니다. 그런 다음 결과 배열을 인쇄하십시오.
juanmf

개념적으로 중요한 3 가지 행렬이 있습니다. Inner, curret & M. 절대 행 및 열 계산에 유용합니다. 내부에서 n을 빼면 전류가 (n이 떨어지는) 나선형 라운드의 상대적 정수가 남습니다. 그리고 M과 현재 순서의 차이는 절대 값을 얻기 위해 현재 라운드에서 행과 열에 대한 오프셋으로 재생됩니다.
juanmf

fn 논리 인라인을 작성하고 사용하지 않는 테스트를 제거하여 364-> 240
juanmf
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.