ลำดับเกลียว


29

พื้นหลัง

ลำดับ OEIS A272573อธิบายถึงเกลียวบนกริดหกเหลี่ยมดังนี้:

เริ่มหมุนวนของตัวเลขบนกระเบื้องหกเหลี่ยมโดยมีหกเหลี่ยมเริ่มต้นเป็น (1) = 1 a (n) เป็นจำนวนเต็มบวกที่เล็กที่สุดที่ไม่เท่ากับหรือก่อนหน้านี้ติดกับเพื่อนบ้าน

ลำดับเริ่มต้น

1, 2, 3, 4, 5, 6, 7, 4, 6, 8, 5, 9, 8, 10, 2, 11, ...

นี่คือภาพประกอบของรูปแบบเกลียว: ป้อนคำอธิบายรูปภาพที่นี่

  • a(11) != 1เพราะตอนนั้น3และ1จะอยู่ติดกันสองแห่ง
  • a(11) != 2เพราะตอนนั้น3และ2จะอยู่ติดกันสองแห่ง
  • a(11) != 3เพราะจากนั้น3จะติดกับตัวเอง
  • a(11) != 4เพราะตอนนั้น3และ4จะอยู่ติดกันสองแห่ง
  • a(11) = 5ดังนั้น

ท้าทาย

ความท้าทายคือการเขียนโปรแกรมที่คำนวณA272573 นี่คือดังนั้นรหัสที่สั้นที่สุดจึงชนะ


ฉันไม่เห็นภาพขณะที่ถูกบล็อกที่นี่ดังนั้นฉันอาจจะพลาดบางอย่าง แต่ตัวอย่างของคุณแสดง (11) = 4 แต่ในรายการลำดับของคุณ (11) คือ 5
Geobits

ผิดพลาด - ขอบคุณที่จับมัน
Peter Kagey

7
ลำดับ OEIS นี้ถูกส่งโดยตัวคุณเอง ดี :)
Arnauld

ขีด จำกัด ของ n คืออะไร มีการ จำกัด เวลาหรือไม่?
Setop

5
รอคำตอบ Hexagony ...
Jonathan Allan

คำตอบ:


23

JavaScript (ES6),  267 .. 206  199 ไบต์

ส่งคืนอาร์เรย์ที่มียังไม่มีข้อความเงื่อนไขแรกของลำดับ

n=>(F=v=>++i<n?F([...v,(A=N[i]=[1,!j++||d+1,j%L?d:(j%=L*6)?++d:L++&&d++].map(k=>N[k=i-k].push(i)&&k),g=k=>v[E='every']((V,x)=>V-k|N[x][E](y=>A[E](z=>v[y]-v[z])))?k:g(-~k))()]):v)([L=1],N=[[i=j=d=0]])

ลองออนไลน์!

อย่างไร?

คำนิยาม

โดยการประชุมเราจะเรียกเซลล์มุม - เซลล์ที่มีเพียงหนึ่งขอบที่เหมือนกันกับชั้นก่อนหน้าของเกลียวและเซลล์ด้านข้างเซลล์ที่มีสองขอบเหมือนกันกับชั้นก่อนหน้า ในฐานะที่เป็นปัญหาโดย Ourous เรายังสามารถคิดว่าพวกเขาเป็นคำสั่งที่ 1 เซลล์และการสั่งซื้อ-2 เซลล์ตามลำดับ

มุมเซลล์จะแสดงเป็นสีเหลืองด้านล่าง เซลล์อื่นทั้งหมดเป็นเซลล์ด้านข้าง (ยกเว้นเซลล์กึ่งกลางซึ่งเป็นกรณีพิเศษ)

ชนิดของเซลล์

เกี่ยวกับเซลล์เพื่อนบ้าน

เราไม่จำเป็นต้องติดตามพิกัดของเซลล์ในตาราง สิ่งเดียวที่เราต้องรู้คือรายการของเซลล์เพื่อนบ้านสำหรับแต่ละเซลล์ในเกลียวในเวลาใดก็ตาม

ในแผนภาพต่อไปนี้เพื่อนบ้านในเลเยอร์ก่อนหน้าจะแสดงในที่ร่มและเพื่อนบ้านเพิ่มเติมในเลเยอร์ปัจจุบันในที่มืดกว่า

เซลล์มี2 เพื่อนบ้านในเซลล์ก่อนหน้าถ้า:

  • เป็นเซลล์ด้านแรกของเลเยอร์ใหม่ (เช่น8 )
  • หรือเป็นเซลล์มุม แต่ไม่ใช่เซลล์สุดท้าย (เช่น9 )

2 เพื่อนบ้าน

เซลล์มี3 เพื่อนบ้านในเซลล์ก่อนหน้าถ้า:

  • มันเป็นเซลล์ด้านข้าง แต่ไม่ใช่ชั้นแรก (เช่น 10 )
  • หรือเป็นเซลล์มุมสุดท้ายของเลเยอร์ปัจจุบัน (เช่น19 )

3 เพื่อนบ้าน

การดำเนินการตามเซลล์เพื่อนบ้าน

1ผมnA[n] ]

1-1

[                    //
  1,                 // the previous cell is always a neighbor of the current cell
  !j++ || d + 1,     // if this is not the first cell of the layer, the cell at -(d + 1)
                     // is a neighbor (otherwise, we insert 1 twice; doing it that way
                     // saves bytes and having duplicate neighbors is not a problem)
  j % L ?            // if this is a side-cell:
    d                //   the cell at -d is a neighbor
  :                  // else (corner-cell):
    (j %= L * 6) ?   //   if this is not the last cell:
      ++d            //     insert the dummy duplicate neighbor at -(d + 1); increment d
    :                //   else (last cell):
      L++ && d++     //     the cell at -d is a neighbor; increment L; increment d
]                    //

ในรหัสข้างต้น:

  • L1
  • J16×L
  • d

map()kผม-k

.map(k =>
  N[k = i - k].push(i) && k
)

ค้นหาคำต่อไปของลำดับ

kของลำดับโดยใช้ฟังก์ชันตัวช่วยเรียกซ้ำ

nโวลต์[n]

( g =                 // g = recursive function taking
  k =>                // the candidate value k
    v.every((V, x) => // for each previous cell of value V at position x, make sure that:
      V - k           //   V is not equal to k
      |               //   OR
      N[x].every(y => //   for each neighbor y of x:
        A.every(z =>  //     for each neighbor z of the current cell:
          v[y] - v[z] //       the value of y is not equal to the value of z
        )             //     end
      )               //   end
    )                 // end
    ?                 // if the above conditions are fulfilled:
      k               //   stop recursion and return k
    :                 // else:
      g(-~k)          //   try again with k + 1
)()                   // initial call to g with k undefined (this will cause V - k to be
                      // evaluated as NaN and force the 1st iteration to fail)

คำอธิบายที่ดี การปรับปรุงหนึ่งที่เป็นไปได้: การทำให้คำอธิบายในบล็อคโค้ดสามารถมองเห็นได้อย่างสมบูรณ์โดยไม่จำเป็นต้องเลื่อนในแนวนอน (ไม่สำคัญสำหรับรหัส golfed) การดูใน Firefox มี 5 คอลัมน์ที่ซ่อนอยู่ในบล็อครหัสคำอธิบายแรกและ 6 คอลัมน์ที่ซ่อนอยู่ในคอลัมน์ที่สอง
trichoplax

@trichoplax ขอบคุณสำหรับความคิดเห็นและข้อเสนอแนะของคุณ คุณสามารถระบุ Firefox เวอร์ชันใดที่คุณใช้อยู่และบนแพลตฟอร์มใดได้บ้าง ฉันพยายามจัดรูปแบบบล็อคคำอธิบายเสมอเพื่อไม่จำเป็นต้องเลื่อนแนวนอน ฉันใช้ Firefox 65 / Win10 อยู่ในขณะนี้และฉันไม่มีคอลัมน์ที่ซ่อนอยู่
Arnauld

จะตรวจสอบเวอร์ชันของ Firefox เมื่อฉันกลับถึงบ้าน แต่อาจเป็นเพราะฉันใช้ Fedora อยู่ จะตรวจสอบระบบปฏิบัติการอื่นและแจ้งให้คุณทราบ
trichoplax

1
ดูเหมือนว่าจะแตกต่างกันไปตามระบบปฏิบัติการ จะยกเรื่องนี้ขึ้นใน MSE เมื่อฉันมีโอกาสรวบรวมหลักฐาน (ถ้ายังไม่ได้รับ)
trichoplax

1
ผมเคยยกนี้ MSE อย่าลังเลที่จะแก้ไขหากใครเห็นระบบปฏิบัติการอื่น ๆ / ชุดเบราว์เซอร์อื่น ๆ ที่แสดงแถบเลื่อนแนวนอน
trichoplax

7

ทำความสะอาด , 284 279 272 262 ไบต์

import StdEnv
l=[0,-1,-1,0,1,1]
c(u,v)(p,q)=(u-p)^2+(v-q)^2<2||(u-p)*(q-v)==1
$[h:t]m=hd[[e: $t[(h,e):m]]\\e<-[1..]|and[e<>j\\(u,v)<-m|c h u,(p,q)<-m|q==v,(i,j)<-m|c p i]]

$(scan(\(a,b)(u,v)=(a-u,b-v))(0,0)[(i,j)\\n<-[1..],i<-[1,1:l]&j<-l,_<-[max(~j<<i)1..n]])[]

ลองออนไลน์!

สร้างลำดับตลอดไป

การทำแผนที่หกเหลี่ยม

รหัสส่วนใหญ่เข้าสู่การจับคู่รูปหกเหลี่ยมเพื่อ(x,y)พิกัดโดยเฉพาะเพื่อให้มีฟังก์ชั่นเดียวที่ง่ายในการตรวจสอบว่าคำใดคำหนึ่งที่เก็บไว้สำหรับการแมปจุดทั้งหมด

จุดที่แมปมีลักษณะดังนี้:

              ---
        --- < 2,-2> ---       x-axis ___.X'
  --- < 1,-2> === < 2,-1> ---  /__.X'
< 0,-2> === < 1,-1> === < 2, 0>'
  === < 0,-1> === < 1, 0> ===
<-1,-1> === < 0, 0> === < 1, 1>
  === <-1, 0> === < 0, 1> ===
<-2, 0> === <-1, 1> === < 0, 2>.__
  --- <-2, 1> === <-1, 2> ---  \  'Y.___
        --- <-2, 2> ---       y-axis    'Y.
              ---

จากตรงนั้นการพิจารณาคำคุณศัพท์นั้นเป็นเรื่องเล็กน้อยและเกิดขึ้นเมื่อ:

  • x1 == x2 และ abs(y1-y2) == 1
  • y1 == y2 และ abs(x1-x2) == 1
  • y1 == y2 - 1 และ x2 == x1 - 1
  • y1 == y2 + 1 และ x2 == x1 + 1
  • x1 == x2 และ y1 == y2

การสร้างจุด

โปรดสังเกตว่าเมื่อทำการสำรวจหกเหลี่ยมในเกลียวความแตกต่างเกิดขึ้นอีกในแต่ละชั้นn:

  1. n ขั้นตอนของ (1,0)
  2. n-1 ขั้นตอนของ (1,-1)
  3. n ขั้นตอนของ (0,-1)
  4. n ขั้นตอนของ (-1,0)
  5. n ขั้นตอนของ (-1,1)
  6. n ขั้นตอนของ (0,1)

สิ่งนี้สร้างคะแนนตามลำดับที่ถูกต้องโดยรับผลรวมของคำนำหน้าของลำดับนี้:

scan(\(a,b)(u,v)=(a-u,b-v))(0,0)[(i,j)\\n<-[1..],i<-[1,1:l]&j<-l,_<-[max(~j<<i)1..n]]

นำมารวมกัน

รหัสที่พบจริงลำดับจากคำถามเป็นเพียง:

$[h:t]m=hd[[e: $t[(h,e):m]]\\e<-[1..]|and[e<>j\\(u,v)<-m|c h u,(p,q)<-m|q==v,(i,j)<-m|c p i]]

ซึ่งส่วนใหญ่แล้วจะถูกกรองโดย and[r<>j\\(u,v)<-m|c h u,(p,q)<-m|q==v,(i,j)<-m|c p i]

ตัวกรองนี้ใช้คะแนนจากm(รายการคะแนนที่แมปแล้ว) โดย:

  • ละเว้นตัวเลขธรรมชาติที่เท่ากับใด ๆ j
  • สำหรับทุก ๆ(i,j)ที่ที่iอยู่ติดกับp
  • สำหรับทุก(p,q)ค่าที่qเท่ากับv
  • สำหรับทุก ๆ(u,v)ที่ที่uอยู่ติดกับจุดปัจจุบัน
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.