Primes of Ulam's Spiral


17

เกลียวของ Ulam เป็นหัวข้อที่น่าสนใจอย่างแท้จริง แต่น่างงงวยในวิชาคณิตศาสตร์ วิธีการทำงานโดยละเอียดสามารถดูได้ที่นี่แต่สามารถสรุปสั้น ๆ ดังนี้:

ฉันเริ่มต้นด้วยการเขียนอันหนึ่งจากนั้นฉันก็เขียนสองอันทางขวาของมัน ด้านบนทั้งสองฉันเขียนสามและทางซ้ายของที่ฉันเขียนสี่ ฉันทำรูปแบบการวนรอบนี้ต่อ 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`` '
Tom Carpenter

5
ตราบใดที่มนุษย์ยังอ่านได้และสามารถบอกสิ่งที่ฉันรู้สึกได้
Addison Crump

คำตอบ:


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

โดยพื้นฐานแล้วสิ่งนี้จะสร้างเกลียวขนาดที่ต้องการ (ร้องขอจากผู้ใช้) จากนั้นจัดเรียงเพื่อให้ปรากฏตามลำดับแถวที่ถูกต้อง สิ่งนี้ถูกเก็บไว้ใน ถัดไปจะแสดงค่าทั้งหมดซึ่งเป็นค่าเฉพาะ

ตามที่คุณพูดทุกรูปแบบที่อ่านได้ฉันบันทึกไบต์และไปหาเอาต์พุตเริ่มต้นของ 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ฟังก์ชั่นนั้น
Luis Mendo

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

Mathematica 223

สิ่งนี้เหมาะสมกับรหัสของ Kubaสำหรับเกลียว Ulam นั่นเป็นเหตุผลที่ฉันส่งมันเป็นวิกิชุมชน ฉันแค่เล่นกอล์ฟและเลือกเฉพาะช่วงเวลาซึ่งอยู่ในรายการตามแถวที่พวกเขาอาศัยอยู่

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

ie เริ่มจากศูนย์กลางจากนั้นเลื่อน 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 Bytes

วิธีการแก้ปัญหาของฉันไม่ได้สร้างเมทริกซ์หนาแน่นด้วยเกลียว แต่จะส่งกลับดัชนีที่สอดคล้องกับจำนวนที่กำหนดในเมทริกซ์ Ulam ของคำสั่งที่กำหนด มันวนซ้ำระหว่างตัวเลข 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


นั่นเป็นการบีบอัดค่อนข้างน้อย คุณสามารถอธิบายรหัสเดิมและการเปลี่ยนแปลงของคุณได้หรือไม่?
Addison Crump

ฉันลบวงเล็บไร้ประโยชน์ออกแล้ว และตระหนักว่า uI () มี 4 เงื่อนไขด้วยบล็อกที่คล้ายกัน แต่ละบรรทัดมี 3 บรรทัดที่สร้างแถวและ Collumn สำหรับกลุ่มปัจจุบัน (ดูที่ docblock หลัก) ดังนั้นฉันจึงแทนที่ thos 4 บล็อกด้วย & llt บรรทัดและบรรทัดส่งคืนจะตัดสินว่า llt เป็นแถวหรือคอลัมน์ S & 2 เป็นจริงสำหรับ s ใน (3,2) (ส่วนบนและด้านซ้าย); s <3, สำหรับ s ใน (1,2) ถูก & บน S & 1, สำหรับใน (1,3) จะกำหนดว่าค่าใน & 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. มีประโยชน์สำหรับการคำนวณแถวและคอลัมน์แบบสัมบูรณ์ Substracting ด้านในถึง n ทำให้เรามี int ญาติในปัจจุบัน (หนึ่งในที่ n ตก) รอบเกลียว และความแตกต่างระหว่างคำสั่งของ M และคำสั่งปัจจุบันจะเล่นเป็นออฟเซ็ตสำหรับแถวและคอลัมน์ในรอบปัจจุบันเพื่อให้ได้ค่าสัมบูรณ์
juanmf

364 -> 240 โดยการเขียนตรรกะแบบอินไลน์ fn และลบการทดสอบที่ไม่ได้ใช้
juanmf
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.