กำลังวิเคราะห์ลำดับที่เหมือน Collatz


12

เรากำหนดลำดับเหมือนCollatzsด้วยจำนวนเต็มบวก 4 ตัว:

  • n ค่าเริ่มต้น
  • d > 1 จำนวนหาร
  • m > 1 ตัวคูณ
  • i การเพิ่มขึ้น

(ในลำดับ Collatz ดั้งเดิมd = 2 m = 3และi = 1.)

กำหนดจำนวนเต็มเหล่านี้sจะถูกสร้างขึ้นในลักษณะดังต่อไปนี้:

  • s(0) = n
  • ถ้าk > 0และs(k-1) mod d = 0แล้วs(k) = s(k-1) / d
  • ถ้าk > 0และs(k-1) mod d != 0แล้วs(k) = s(k-1) * m + i

ลำดับเช่นกับd = 2, m = 3, i = 5และจะn = 80s = 80, 40, 20, 10, 5, 20, 10, 5, 20, ...

ทุกลำดับจะถึงค่าที่สูงกว่าขอบเขตที่กำหนด (เช่นลำดับนั้นแตกต่างกัน) หรือเข้าสู่วงวนไม่สิ้นสุดหากสำหรับบางส่วนtและu( t!=u) s(t) = s(u)ความเท่าเทียมกันจะเป็นจริง

ในปัญหาของเราหากค่าขององค์ประกอบลำดับนั้นมีขนาดใหญ่กว่า10^9หรือไม่มีการทำซ้ำองค์ประกอบก่อนที่1000องค์ประกอบที่ลำดับนั้นถือว่าแตกต่างกัน

งาน

คุณควรเขียนโปรแกรมหรือฟังก์ชั่นที่รับจำนวนเต็มบวกd mและiเป็นอินพุตและเอาท์พุตชนิดสิ้นสุดที่แตกต่างกันทั้งหมดของลำดับ (วนซ้ำไม่สิ้นสุดและความแตกต่าง) ซึ่งค่าเริ่มต้นn = 1, 2, 3, ... 999, 1000สามารถสร้างได้

ใส่รายละเอียด

  • การป้อนข้อมูลที่เป็นสตริงหรือรายการ (หรือเทียบเท่าใกล้เคียงที่สุดในภาษาของคุณ) เป็นตัวแทน (ในวิธีการทั่วไป) สามจำนวนเต็มบวกd, mและiอยู่ในลำดับที่ dและอย่างน้อยm ทั้งจำนวนมีขนาดใหญ่กว่า2100

รายละเอียดผลลัพธ์

สเปคเอาท์พุทเป็นคำพูดเล็กน้อย อาจคุ้มค่าที่จะดูตัวอย่างก่อน

  • คุณควรส่งออกไปยังเอาต์พุตมาตรฐาน (หรือทางเลือกที่ใกล้เคียงที่สุด) หรือส่งคืนสตริง
  • DIVERGENTถ้าลำดับที่แตกต่างกันเป็นไปได้ในบรรทัดแรกที่ควรจะเป็น
  • การแสดงที่เป็นเอกลักษณ์ของการวนซ้ำของลำดับคือการหมุนโดยที่จำนวนที่เล็กที่สุดจะถูกคั่นด้วยช่องว่างสุดท้าย เช่นถ้าห่วงคือs = 2 1 4 2 1 4 2 14 2 1
  • LOOPในบรรทัดต่อไปนี้ทุกครั้งที่คุณควรส่งออกทุกวงที่ไม่ซ้ำกันว่าครั้งหนึ่งเคยนำหน้าด้วยคำว่า เช่นLOOP 4 2 1
  • ลูปควรเรียงจากน้อยไปมากตามองค์ประกอบสุดท้ายของพวกเขา
  • ขึ้นบรรทัดใหม่ต่อท้ายเป็นตัวเลือก

ตัวอย่าง:

บรรทัดแรกคืออินพุตและบรรทัดต่อไปนี้จนกว่าบรรทัดว่างจะเป็นเอาต์พุต

2 3 1
LOOP 4 2 1

2 2 6
LOOP 8 4 2 1
LOOP 12 6 3

3 7 8
DIVERGENT
LOOP 15 5 43 309 103 729 243 81 27 9 3 1
LOOP 22 162 54 18 6 2
LOOP 36 12 4

3 9 1
DIVERGENT

6 9 9
DIVERGENT
LOOP 18 3 36 6 1
LOOP 27 252 42 7 72 12 2
LOOP 45 414 69 630 105 954 159 1440 240 40 369 3330 555 5004 834 139 1260 210 35 324 54 9 90 15 144 24 4
LOOP 81 738 123 1116 186 31 288 48 8
LOOP 99 900 150 25 234 39 360 60 10
LOOP 126 21 198 33 306 51 468 78 13

10 10 10
LOOP 20 2 30 3 40 4 50 5 60 6 70 7 80 8 90 9 100 10 1

93 91 92
DIVERGENT
LOOP 2185 198927 2139 23
LOOP 4278 46

การใช้งานอ้างอิงใน Python 3 บน Ideone

นี่คือรหัสกอล์ฟที่สั้นที่สุดที่จะชนะ

คำตอบ:


5

Python 3, 269 254 252 246 ไบต์

d,m,i=eval(input())
S=set()
for n in range(1,1001):
 T=X=()
 while len(T)**3<1e9>=n:
  T=(n,)+T;n=[n//d,n*m+i][n%d>0]
  if n in T:I=T.index;L=T[:I(n)+1];M=I(min(L));X=L[M:]+L[:M]
 S|={X}
for x in sorted(S):print(x and"LOOP"or"DIVERGENT",*x[::-1])

(ตอนนี้ช้าลง 10 เท่าเพื่อบันทึกสองสามไบต์โค้ดกอล์ฟทั่วไป)

ป้อนรายการผ่าน STDIN (เช่น[2, 3, 1]) ฉันคิดว่าจะต้องมีวิธีที่ดีกว่าในการกำหนดมาตรฐานของรอบ ...

วิธีการนั้นค่อนข้างตรงไปตรงมา - ทดสอบจำนวน 1,000 หมายเลขและรับเฉพาะผลลัพธ์ที่ไม่ซ้ำกัน อย่างไรก็ตามมีสองเทคนิคเล็ก ๆ น้อย ๆ ในนั้น:

  • ลูปถูกแทนด้วย tuples ที่ไม่ว่างเปล่าแต่ที่สำคัญกว่านั้นคือความแตกต่างที่สำคัญคือtuple ที่ว่างเปล่า นี่เป็นสิ่งที่ดีเพราะ:

    • มันไม่แตกsortedและจะปรากฏต่อหน้าห่วงลูปทั้งหมด
    • มันช่วยให้เราสามารถเลือกสตริงผ่าน x and"LOOP"or"DIVERGENT"
    • *()[::-1] ไม่ส่งผลกระทบ print
  • ห่วงถูกสร้างขึ้นข้างหลังเพื่อเปิด "เรียงลำดับจากน้อยไปมากโดยองค์ประกอบสุดท้าย" เป็น "การจัดเรียงจากน้อยไปมากโดยองค์ประกอบแรก" sortedซึ่งขจัดความจำเป็นในการที่จะผ่านเข้ามาในแลมบ์ดา

การส่งก่อนหน้า 252 ไบต์

d,m,i=eval(input())
def f(n,T=()):
 x=[n//d,n*m+i][n%d>0];I=T.index
 if x in T:L=T[:I(x)+1];M=I(min(L));return L[M:]+L[:M]
 return()if(T[1000:]or x>1e9)else f(x,(x,)+T)
for x in sorted(set(map(f,range(1,1001)))):print(x and"LOOP"or"DIVERGENT",*x[::-1])

คนนี้เร็วขึ้นมาก

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