เกลียวละแวกบ้าน


19

หากเรานำจำนวนธรรมชาติมารวมกันแล้วหมุนนาฬิกานับเป็นเกลียวให้กลายเป็นเกลียว

                  ....--57--56
                             |
36--35--34--33--32--31--30  55
 |                       |   |
37  16--15--14--13--12  29  54
 |   |               |   |   |
38  17   4---3---2  11  28  53
 |   |   |       |   |   |   |
39  18   5   0---1  10  27  52
 |   |   |           |   |   |
40  19   6---7---8---9  26  51
 |   |                   |   |
41  20--21--22--23--24--25  50
 |                           |
42--43--44--45--46--47--48--49

เมื่อพิจารณาตัวเลขในเกลียวนั้นงานของคุณคือกำหนดเพื่อนบ้าน - หมายถึงองค์ประกอบด้านบนซ้ายขวาและใต้

ตัวอย่าง

ถ้าเราดูที่27เราจะเห็นว่ามันมีเพื่อนบ้านต่อไปนี้:

  • ข้างบน: 28
  • ซ้าย: 10
  • ขวา: 52
  • ด้านล่าง: 26

ดังนั้นผลลัพธ์จะเป็น: [28,10,52,26]

กฎระเบียบ

  • การป้อนข้อมูลจะมีจำนวนในใด ๆเริ่มต้นผมรูปแบบ / On0
  • ผลลัพธ์จะเป็นลิสต์ / เมทริกซ์ / .. ของ 4 ตัวเลขเพื่อนบ้านในลำดับ (สอดคล้อง!)
  • คุณอาจใช้เกลียวที่ขึ้นต้นด้วย 1 แทนที่จะเป็น 0 อย่างไรก็ตามคุณควรระบุในคำตอบของคุณ

ตัวอย่าง

เอาต์พุตอยู่ในรูปแบบ[above,left,right,below]และใช้เป็นเกลียวแบบอิง 0:

0  ->  [3,5,1,7]
1  ->  [2,0,10,8]
2  ->  [13,3,11,1]
3  ->  [14,4,2,0]
6  ->  [5,19,7,21]
16  ->  [35,37,15,17]
25  ->  [26,24,50,48]
27  ->  [28,10,52,26]
73  ->  [42,72,74,112]
101  ->  [100,146,64,102]
2000  ->  [1825,1999,2001,2183]
1000000  ->  [1004003,1004005,999999,1000001]

คำตอบ:


6

R , 156 ไบต์

function(n){g=function(h)c(0,cumsum(h((4*(0:(n+2)^2)+1)^.5%%4%/%1/2)))
x=g(sinpi)
y=g(cospi)
a=x[n]
b=y[n]
which(x==a&(y==b+1|y==b-1)|y==b&(x==a+1|x==a-1))}

ลองออนไลน์!

  • โพสต์คำตอบ R อื่นเนื่องจากเป็นแนวทางที่แตกต่างจาก @ngn เล็กน้อย
  • 1 การจัดทำดัชนี
  • เพื่อนบ้านจะเรียงตามค่าจากน้อยไปมาก
  • บันทึก 6 ไบต์การลบroundและการใช้cospi(x)/sinpi(x)ซึ่งมีความแม่นยำมากกว่าcos(x*pi)/sin(x*pi)ในกรณีของตัวเลขครึ่งหนึ่ง ( 0.5,1.5ฯลฯ ... )
  • บันทึกอีกไบต์หนึ่งลบเครื่องหมายลบบนพิกัด y เนื่องจากผลลัพธ์เหมือนกัน (เพิ่งขึ้น / ลงเพื่อนบ้านจะกลับด้าน)

คำอธิบาย:

หากเราดูพิกัดเมทริกซ์ของค่าโดยพิจารณาจากค่าแรกที่0ใส่ไว้x=0, y=0นั่นคือ:

x = [0,  1,  1,  0, -1, -1, -1,  0,  1,  2,  2,  2,  2,  1,  0, ...] 
y = [0,  0,  1,  1,  1,  0, -1, -1, -1, -1,  0,  1,  2,  2,  2, ...]

xพิกัดตามลำดับ A174344 OEISกับสูตร recursive:

a(1) = 0, a(n) = a(n-1) + sin(mod(floor(sqrt(4*(n-2)+1)),4)*pi/2)

สูตรเดียวกันมีไว้สำหรับyพิกัดเมทริกซ์ แต่มีcosแทนsinและ negated:

a(1) = 0, a(n) = a(n-1) - cos(mod(floor(sqrt(4*(n-2)+1)),4)*pi/2)

ดังนั้นใน R เราสามารถแปลสูตรเป็นฟังก์ชันนี้โดยรับsinpi/cospiพารามิเตอร์:

g=function(h)c(0,cumsum(h((4*(0:(n+2)^2)+1)^.5%%4%/%1/2)))

และเราสร้างเวกเตอร์พิกัดสองอัน (เราไม่คัดค้าน y coords เนื่องจากเราจะได้ผลลัพธ์เหมือนกันโดยมีเพื่อนบ้านขึ้น / ลงย้อนกลับ):

x=g(sinpi)
y=g(cospi)

โปรดทราบว่าเราได้สร้าง(n+2)^2พิกัดซึ่งเป็นมากกว่าพิกัดขั้นต่ำที่จำเป็นซึ่งมีทั้งคู่nและเพื่อนบ้านของพวกเขา(floor(sqrt(n))+2)^2แต่น่าเสียดายที่ "golfy" น้อยกว่า)

ดังนั้นเมื่อเรามีพิกัดทั้งหมดเราจะค้นหาพิกัดที่a,bสอดคล้องกับของเราก่อนn:

a=x[n]
b=y[n]

ในที่สุดเราก็เลือกตำแหน่งของเพื่อนบ้าน ได้แก่ :

  • เพื่อนบ้านขึ้น / ลง where x == a and y == b+1 or b-1
  • เพื่อนบ้านขวา / ซ้าย where y == b and x == a+1 or a-1

ใช้:

which(x==a&(y==b+1|y==b-1)|y==b&(x==a+1|x==a-1))

"แตกต่างกันเล็กน้อย" :)
ngm

@ngm: eheh ... เนื่องจากรหัส rosetta ที่คุณใช้นั้นค่อนข้าง "คลุมเครือ" สำหรับฉันฉันคิดว่าจะสร้างดัชนีตำแหน่งของเมทริกซ์ด้วยวิธีที่แตกต่างกัน แต่คล้ายกันกว่าลำดับ OEIS ของฉัน: D
digEmAll

4

Perl 6 , 94 83 ไบต์

{my \ s = 0, | [+] flat ((1, i ... ) Zxx flat (1..Inf Z 1..Inf)); map {แรก: k, s [$ _] + $ ^ d, s} i, -1,1, -i}

{my \s=0,|[\+] flat((1,*i...*)Zxx(1,1.5...*));map {first :k,s[$_]+$^d,s},i,-1,1,-i}

ลองออนไลน์!

sเป็นรายการเกลียวที่ไม่สิ้นสุดและไม่มีที่สิ้นสุดของพิกัดเกลียวซึ่งแสดงเป็นจำนวนเชิงซ้อน มันสร้างขึ้นมาจากสองรายการอื่น ๆ ที่ไม่มีที่สิ้นสุด: ทำรายการ 1, *i ... * ทำให้รายการ ซิปทั้งสองรายการด้วยกันกับการจำลองแบบรายการผลิตรายการของขั้นตอนจากแต่ละเกลียวประสานงานต่อไปนี้: (ส่วนที่เป็นเศษส่วนของการขัดแย้งทางด้านขวาของตัวดำเนินการจำลองรายการจะถูกยกเลิก) การทำการเพิ่มการลดรูปสามเหลี่ยม ( ) ในรายการนี้ (และการวาง 0 ลงบนด้านหน้า) จะสร้างรายการพิกัดเกลียว1, i, -1, -i ...1, 1.5 ... *1, 1.5, 2, 2.5, 3, 3.5 ...1, i, -1, -1, -i, -i, 1, 1, 1, i, i, i ...[\+]

ในที่สุดก็เริ่มต้นจากจำนวนเชิงซ้อนs[$_]( $_เป็นอาร์กิวเมนต์เดียวที่ฟังก์ชั่น) เรามองขึ้นดัชนี ( first :k) ในเกลียวของตัวเลขที่ซับซ้อนที่มีการชดเชยจากตัวเลขที่โดยi, -1, และ1-i


4

Brain-Flakขนาด 238 ไบต์

((){[()]<((({}[((()))]<>)<<>{((([{}]({}))([{}]{})())[()]){({}[()])<>}{}}>)<<>({}<(((({}{})()){}<>({}))()())<>>)<>>()())<>{{}((()()()[({})]){}<>({}<{}>))(<>)}>}{}){<>((((())()())()())()())(<>)}{}{({}[()]<<>({}<>)<>({}<({}<({}<>)>)>)<>>)}<>

ลองออนไลน์!

เอาต์พุตอยู่ในลำดับซ้ายขึ้นขึ้นขวาลง

คำอธิบาย

# If n is nonzero:
((){[()]<

  ((

    # Push 1 twice, and push n-1 onto other stack.
    ({}[((()))]<>)

    # Determine how many times spiral turns up to n, and whether we are on a corner.
    # This is like the standard modulus algorithm, but the "modulus" used
    # increases as 1, 1, 2, 2, 3, 3, ...
    <<>{((([{}]({}))([{}]{})())[()]){({}[()])<>}{}}>

  # Push n-1: this is the number behind n in the spiral.
  )<

    # While maintaining the "modulus" part of the result:
    <>({}<

      # Push n+2k+1 and n+2k+3 on top of n-1, where k is 3 more than the number of turns.
      # n+2k+1 is always the number to the right in the direction travelled.
      # If we are on a corner, n+2k+3 is the number straight ahead.
      (((({}{})()){}<>({}))()())<>

    >)<>

  # Push n+1.  If we are on a corner, we now have left, front, right, and back
  # on the stack (from top to bottom)
  >()())

  # If not on a corner:
  <>{{}

    # Remove n+2k+3 from the stack entirely, and push 6-2k+(n+1) on top of the stack.
    ((()()()[({})]){}<>({}<{}>))

  (<>)}

>}{})

# If n was zero instead:
{

  # Push 1, 3, 5, 7 on right stack, and implicitly use 1 (from if/else code) as k.
  <>((((())()())()())()())

(<>)}{}

# Roll stack k times to move to an absolute reference frame
# (switching which stack we're on each time for convenience)
{({}[()]<<>({}<>)<>({}<({}<({}<>)>)>)<>>)}<>

ที่น่าประทับใจมาก! ฉันเดาว่าคุณไม่ได้สร้างเกลียวทั้งหมดเหมือนคนอื่นใช่ไหม?
ბიმო

3

MATL , 15 ไบต์

2+1YLtG=1Y6Z+g)

อินพุตและเอาต์พุตเป็นพื้นฐาน 1

เอาต์พุตจะให้เพื่อนบ้านทางซ้าย, ลง, ขึ้นและขวาตามลำดับนั้น

ลองออนไลน์! หรือตรวจสอบกรณีทดสอบทั้งหมดยกเว้นสองกรณีล่าสุดซึ่งหมดเวลาใช้งานกับ TIO

2+      % Implicit input: n. Add 2. This is needed so that
        % the spiral is big enough
1YL     % Spiral with side n+2. Gives a square matrix
t       % Duplicate
G=      % Compare with n, element-wise. Gives 1 for entry containing n
1Y6     % Push 3×3 mask with 4-neighbourhood
Z+      % 2D convolution, keeping size. Gives 1 for neighbours of the
        % entry that contained n
g       % Convert to logical, to be used as an index
)       % Index into copy of the spiral. Implicit display

2
1YL- MATLAB มีspiralฟังก์ชั่นหรือไม่? MATLAB เปลี่ยนเป็น Mathematica เมื่อไหร่!
sundar - Reinstate Monica

ใช่ฉัน duckduckgo-ed หลังจากเห็นว่า 1YL หมายถึงอะไรและรายการรหัส Rosetta นี้เป็นที่เดียวที่ฉันสามารถยืนยันได้ว่ามันเป็น MATLAB ไม่ใช่แค่ฟังก์ชั่นความสะดวกสบายของ MATLAB ฉันเริ่มคิดว่าอาจเป็นสิ่งที่คุณเพิ่มใน MATL สำหรับการเล่นกอล์ฟจนกว่าฉันจะเห็นรายการนั้น
sundar - Reinstate Monica

@sundar แปลกที่ไม่มีการบันทึกอีกต่อไป
Luis Mendo

3

R , 172 ไบต์

function(x,n=2*x+3,i=cumsum(rep(rep(c(1,n,-1,-n),l=2*n-1),n-seq(2*n-1)%/%2))){F[i]=n^2-1:n^2
m=matrix(F,n,n,T)
j=which(m==x,T)
c(m[j[1],j[2]+c(-1,1)],m[j[1]+c(-1,1),j[2]])}

ลองออนไลน์!

นี่คือ R ดังนั้นเห็นได้ชัดว่าคำตอบคือ 0 ดัชนี

งานส่วนใหญ่คือการสร้างเมทริกซ์ โค้ดได้รับแรงบันดาลใจจาก: https://rosettacode.org/wiki/Spiral_matrix#R


2

JavaScript (ES6), 165 ไบต์

alert()พิมพ์ดัชนีด้วย

f=(n,x=w=y=n+2)=>y+w&&[0,-1,0,1].map((d,i)=>(g=(x,y,A=Math.abs)=>(k=A(A(x)-A(y))+A(x)+A(y))*k+(k+x+y)*(y>=x||-1))(x+d,y+~-i%2)-n||alert(g(x,y)))|f(n,x+w?x-1:(y--,w))

ลองออนไลน์!

อย่างไร?

x,YZผมx,Y

Ax,Y=||x|-|Y||+|x|+|Y|
Sx,Y={1,ถ้า Yx-1,ถ้า Y<x
ผมx,Y=Ax,Y2+(Ax,Y+x+Y)×Sx,Y

(ดัดแปลงมาจากคำตอบนี้จาก math.stackexchange)


นี้ดูเหมือนว่าจะทำงานได้ดีกับตัวเลขที่มีขนาดเล็ก แต่ฉันได้รับข้อผิดพลาดเมื่อการทดสอบนี้มีจำนวนมากเช่น 2000 ข้อผิดพลาดใน tio.run: และความผิดพลาดในคอนโซลเบราว์เซอร์:RangeError: Maximum call stack size exceeded InternalError: too much recursionฉันกำลังทำอะไรผิดหรือเปล่า?
Night2

1
@ Night2 จำนวนการวนซ้ำเพิ่มขึ้น 4n2ดังนั้น call stack จะล้นอย่างรวดเร็ว ข้อ จำกัด ประเภทเดียวกันนี้ใช้กับคำตอบแบบเรียกซ้ำ JS ส่วนใหญ่แม้ว่าข้อ จำกัด ที่แน่นอนนั้นขึ้นอยู่กับแพลตฟอร์มที่ใช้งานอยู่
Arnauld


1

PHP (> = 5.4), 208 ไบต์

<?$n=$argv[1];for(;$i++<($c=ceil(sqrt($n))+($c%2?2:3))**2;$i!=$n?:$x=-$v,$i!=$n?:$y=+$h,${hv[$m&1]}+=$m&2?-1:1,$k++<$p?:$p+=$m++%2+$k=0)$r[-$v][+$h]=$i;foreach([0,1,0,-1]as$k=>$i)echo$r[$x+$i][$y+~-$k%2].' ';

วิธีเรียกใช้:

php -n -d error_reporting=0 <filename> <n>

ตัวอย่าง:

php -n -d error_reporting=0 spiral_neighbourhoods.php 2001

หรือลองออนไลน์!

หมายเหตุ:

  • -d error_reporting=0ตัวเลือกที่จะใช้ในการประกาศไม่เอาท์พุท / คำเตือน
  • เกลียวนี้เริ่มต้นด้วย 1

อย่างไร?

ฉันกำลังสร้างเกลียวด้วยคำตอบนี้ในเวอร์ชัน2 มิติที่ได้รับการแก้ไข

ฉันตัดสินใจเกี่ยวกับขนาดของเกลียวตามอินพุตnด้วยสูตรเพื่อให้ได้ตัวเลขรอบพิเศษในเกลียวเสมอ (รับประกันการมีอยู่ของบน / ล่าง / ซ้าย / ขวา / ขวา) ตัวเลขรอบพิเศษหมายถึง+2ความสูงและ+2ความกว้างของอาร์เรย์ 2 มิติ

ดังนั้นถ้าnจะอยู่ในเกลียวที่มีขนาดใหญ่สุด3*3จะเกิดเกลียวขึ้น5*5ขึ้น

ขนาดเกลียวอยู่c*cตรงไหนc = ceil(sqrt(n)) + kถ้าceil(sqrt(n))เป็นคี่แล้วก็kคือ 2 และถ้าceil(sqrt(n))เป็นเลขคู่kคือ 3

ตัวอย่างเช่นสูตรด้านบนจะส่งผลดังนี้:

  • ถ้าเป็นเช่นn = 1นั้นc = 3และขนาดเกลียวจะเป็น3*3
  • ถ้าเป็นเช่นn <= 9นั้นc = 5และขนาดเกลียวจะเป็น5*5
  • ถ้าเป็นเช่นn <= 25นั้นc = 7และขนาดเกลียวจะเป็น7*7
  • ถ้าเป็นเช่นn <= 49นั้นc = 9และขนาดเกลียวจะเป็น9*9
  • และอื่น ๆ ...

ในขณะที่สร้างเกลียวฉันเก็บxและyของnและหลังรุ่นผมเอาท์พุทองค์ประกอบด้านบน / ด้านล่าง / ซ้าย / ขวาของมัน

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