Số nguyên tố của xoắn ốc Ulam


17

Xoắn ốc của Ulam là một chủ đề thực sự hấp dẫn, nhưng khó hiểu trong toán học. Làm thế nào nó hoạt động chi tiết có thể được tìm thấy ở đây , nhưng một bản tóm tắt ngắn có thể được giải thích như vậy:

Tôi bắt đầu bằng cách viết một cái, sau đó tôi viết một cái ở bên phải của nó. Trên hai, tôi viết ba, và bên trái tôi viết bốn. Tôi tiếp tục mô hình xoay quanh 1 (và bất kỳ số nào giữa tôi và 1) vô hạn (hoặc cho đến khi được bảo dừng lại), tạo thành một mô hình xoắn ốc. (xem ví dụ dưới đây)

Mục tiêu

Tạo một chương trình chấp nhận n (sẽ luôn là số lẻ lớn hơn 0) làm đầu vào tương quan với số lượng hàng, sau đó in ra các giá trị của hàng số nguyên tố theo hàng của vòng xoắn ốc Ulam. Các định dạng có thể là bất kỳ thời trang, nhưng phải có thể đọc được và rõ ràng của con người.

Ví dụ: với đầu vào 3, chương trình của bạn sẽ xuất ra 5,3,2,7, vì 3 hàng tạo ra hình xoắn ốc sau:

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

Vì đây là một môn đánh gôn, câu trả lời có ít byte nhất sẽ thắng (dù hiệu quả đến đâu)! Sơ hở tiêu chuẩn không được chấp nhận.


Dấu phẩy có được phép không? Hoặc tốt hơn là, không gian được phân tách, ví dụ: `` `5 3 2 7```
Tom Carpenter

5
Miễn là nó có thể đọc được và có thể cho tôi biết các số nguyên tố, hãy thoải mái.
Addison Crump

Câu trả lời:


8

Bình thường, 20 byte

f}TPTsuC+R=hZ_GtyQ]]

Dùng thử trực tuyến: Trình diễn

Mã này tạo ra vòng xoắn hoàn toàn của Ulam, kết nối tất cả các dòng và bộ lọc cho các số nguyên tố.

Giải trình:

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)))

Về cơ bản, điều này tạo ra một vòng xoắn có kích thước yêu cầu (được yêu cầu từ người dùng), sau đó sắp xếp nó để nó xuất hiện theo đúng thứ tự hàng. Điều này được lưu trữ trong một. Tiếp theo, nó hiển thị tất cả các giá trị trong đó là số nguyên tố.

Như bạn đã nói bất kỳ định dạng có thể đọc được, tôi đã lưu một byte và đi đến đầu ra mặc định của dist () là (trong trường hợp thử nghiệm của bạn, n = 3):

 5
 3
 2
 7

Là một phần thưởng bổ sung, điều này hoạt động với mọi n> 0, bao gồm cả số chẵn. Ví dụ: đầu ra cho n = 10 là:

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
Rất đẹp! Thật tốt khi biết spiralchức năng đó
Luis Mendo

6

CJam, 42 33 byte

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

Dùng thử trực tuyến

Phiên bản mới nhất bao gồm những cải tiến đáng kể được đề xuất bởi @Martin.

Phương pháp để xây dựng hình xoắn ốc là, trong mỗi bước, xoay ma trận chúng ta có đến 90 độ và thêm một hàng với các số bổ sung. Đây là lần lặp lại (n / 2) * 4.

Các giá trị trong ma trận kết quả sau đó được lọc để trở thành số nguyên tố.

Giải trình:

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.

Có thể 2/4*được thay thế bởi 2*, hoặc bạn đã để nó như vậy trên mục đích?
Sản xuất ETH

@ETHproductions Điều đó không tương đương vì đó là một phép chia số nguyên. Ví dụ, đối với đầu vào 3, kết quả cần phải là 4. Thực tế, bây giờ tôi nghĩ về nó, tôi tin rằng có một byte được lưu. (2*nên chính xác
Reto Koradi

5

Toán học 223

Điều này chiếm đoạt mã của Kuba cho một vòng xoắn ốc Ulam. Đó là lý do tại sao tôi gửi nó như một wiki cộng đồng. Tôi chỉ chơi golf và chọn ra các số nguyên tố được liệt kê theo hàng mà chúng cư trú.

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]

Thí dụ

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

Để cải thiện màn hình:

 %// MatrixForm

ma trận


4

Toán học, 118 byte

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

Điều này tạo ra xoắn ốc Ulam ở dạng tuyến tính bằng cách lưu ý rằng vị trí của mỗi số tiếp theo có thể được tích lũy như

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

tức là bắt đầu từ trung tâm, sau đó di chuyển 1 phải, 1 lên, 2 trái, 2 xuống, 3 phải, 3 lên, ...

Đầu ra:

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

1

Javascript, 516 363 304 276 243 240 byte

Giải pháp của tôi không tạo ra một ma trận dày đặc với Xoắn ốc, thay vào đó, nó trả về chỉ số tương ứng với số đã cho trong Ma trận của Ulam theo thứ tự đã cho. Vì vậy, nó lặp qua các số từ 2 đến M * M và tạo ra một mảng các số nguyên tố với idx được đưa ra bởi 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);

Hình thu nhỏ trông như thế này:

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);

Đối với đầu vào 15, đầu ra là:

,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, , 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


Đó là một chút nén. Bạn có thể giải thích mã gốc của bạn và những thay đổi của bạn?
Addison Crump

Tôi loại bỏ một số dấu ngoặc vô dụng. Và nhận ra rằng uI () có 4 điều kiện với các khối tương tự. Mỗi dòng có 3 dòng tạo Row và Collumn cho phân khúc hiện tại (xem docblock chính) vì vậy tôi thay thế 4 khối bằng các dòng ll & llt và dòng trả về quyết định xem llt là hàng hay cột. S & 2 đúng với s trong (3,2) (phân đoạn trên & bên trái); s <3, cho s trong (1,2) phải & trên. S. cần ll-1
juanmf

Trong vòng lặp chính (run ()) chỉ khi i là số nguyên tố (mà fn đã giảm vì không bao giờ cần kiểm tra <2 hay% 1), nó yêu cầu chỉ số của tôi (ll, llt) trong vòng xoắn ốc, điều này có thể được sửa. Sau đó chỉ cần in mảng kết quả.
juanmf

Có 3 ma trận quan trọng về mặt khái niệm. Bên trong, dòng và M. Hữu ích cho việc tính toán hàng tuyệt đối & col. Trừ đi bên trong để n để lại cho chúng ta một int tương đối trong dòng điện (một trong đó n rơi) vòng xoắn ốc. Và sự khác biệt giữa thứ tự của M và hiện tại đóng vai trò bù cho hàng và col trong vòng hiện tại để có được số tuyệt đối.
juanmf

364 -> 240 bằng cách viết nội tuyến logic fn và loại bỏ các kiểm tra không sử dụng.
juanmf
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.