การวิ่งในสตริงที่ไม่สิ้นสุดนี้อยู่ที่ไหน (พบ CCCCCC!)


25

เริ่มต้นด้วยสตริงABCพิจารณาผลลัพธ์ของการต่อท้ายครึ่งสุดท้ายของตัวเองเข้ากับตัวเองซ้ำ ๆ (ใช้ครึ่งที่ใหญ่กว่าถ้าความยาวเป็นเลขคี่)

เราได้รับความก้าวหน้า:

ABC
ABCBC
ABCBCCBC
ABCBCCBCCCBC
ABCBCCBCCCBCBCCCBC
etc...

อนุญาตให้Sแสดงสตริงอนันต์ที่เกิดขึ้น (หรือลำดับ) ที่ผลลัพธ์เมื่อโพรซีเดอร์นี้ซ้ำไปเรื่อย ๆ

เป้าหมาย

เป้าหมายในการท้าทายรหัสนี้คือการหาดัชนีของเกิดขึ้นครั้งแรกของการทำงานของC's Sใน

มันง่ายในตอนแรก: Cเกิดขึ้นครั้งแรกที่ดัชนี2, CCที่4, CCCที่7, CCCCที่26, แต่CCCCCเป็นไปตามดัชนี27308! หลังจากนั้นความจำของฉันก็หมด

ผู้ชนะจะได้รับการส่งที่สร้างดัชนีได้อย่างถูกต้องมากที่สุด (ตามลำดับเริ่มต้นที่C) คุณสามารถใช้อัลกอริทึมแบบใดก็ได้ แต่อย่าลืมอธิบายถ้าคุณไม่ได้ใช้กำลังดุร้ายขั้นพื้นฐาน อินพุตและเอาต์พุตสามารถอยู่ในรูปแบบที่เข้าใจง่าย

หมายเหตุสำคัญ:ผมไม่ทราบว่าเป็นทางการหรือไม่Sจริงมีการทำงานทั้งหมดของC's คำถามนี้มาจากคำถามนี้ใน Mathematics Stack Exchangeซึ่งผู้เขียนไม่พบCCCCCCเช่นกัน ฉันอยากรู้ว่าใครที่นี่สามารถ (คำถามนั้นเป็นไปตามคำถามเดิมของฉันในหัวข้อ )

หากคุณสามารถพิสูจน์ได้ว่าไม่Cเกิดขึ้นทั้งหมดในSนั้นคุณจะชนะโดยอัตโนมัติเนื่องจากคำถามนี้จะไม่ถูกต้อง ถ้าไม่มีใครสามารถพิสูจน์ได้ว่ามิได้พบCCCCCCแล้วผู้ชนะจะได้เป็นคนที่จะได้รับสูงสุดลดผูกพันในดัชนีของCCCCCC(หรืออะไรก็ตามที่ใหญ่ที่สุดวิ่งยังไม่แก้คือถ้าCCCCCCพบ)

ปรับปรุง:รุ่งโรจน์ Humongous เพื่อisaacgและresที่ได้พบCCCCCCที่ดัชนีทางดาราศาสตร์ของ 2.124 * 10 ^ 519 ในอัตรานี้ฉันไม่สามารถจินตนาการถึงการค้นหาCCCCCCCด้วยวิธีการใด ๆ พวกทำงานดีมาก!


ฉันไม่เข้าใจ - คุณกำลังบอกว่าคุณพบCCCCCดัชนี 27308 แต่ต่อมาดูเหมือนว่าคุณไม่รู้ว่ามันเกิดขึ้นที่ใด คุณหมายถึงCCCCCCอะไร
isaacg

@isaacg โอ๊ะโอ 6 C เป็นสิ่งที่หายาก ฉันจะแก้ไขมัน
งานอดิเรกของ Calvin

หากการคาดเดาผิดมี N ที่ c ^ N เป็นการวิ่งที่ยาวที่สุด ฉันค่อนข้างแน่ใจว่ามันเป็นไปได้ที่จะสร้างลำดับที่ยาวขึ้นนำไปสู่ความขัดแย้งและพิสูจน์การคาดเดา ฉันยังไม่คิดว่ามันยากเกินไป แต่ในทางกลับกันปัญหาสามารถประเมินได้ง่าย ...
Ingo Bürk

ฉันจะกลับมาที่นี่อีกครั้งในเวลาเที่ยงคืนด้วยชุดคะแนนเสียงใหม่ - สำหรับทั้งคำถามและคำตอบ!
trichoplax

สำหรับผู้ที่กำลังค้นหาสิ่งนี้สามารถทำให้ง่ายขึ้นเล็กน้อย: หากคุณลบ "A" ตัวแรกคุณจะต้องเล่นกับ "AB" เท่านั้นและคุณจะเพิ่มอีกครึ่งหนึ่งสำหรับการทำซ้ำครั้งถัดไป
Faquarl

คำตอบ:


23

CCCCCC พบได้ที่ 2.124 * 10 ^ 519

ดัชนีแม่นยำเป็น 2124002227156710537549582070283786072301315855169987260450819829164756027922998360364044010386660076550764749849261595395734745608255162468143483136030403857241667604197146133343367628903022619551535534430377929831860918493875279894519909944379122620704864579366098015086419629439009415947634870592393974557860358412680068086381231577773140182376767811142988329838752964017382641454691037714240414750501535213021638601291385412206075763857490254382670426605045419312312880204888045665938646319068208885093114686859061215

พบโดย res โดยใช้รหัส (เวอร์ชั่นเก่า) ด้านล่างหลังจาก 3.5 ชั่วโมงของการค้นหา

รอบดัชนีนั้นสตริงคือ: ...BCCBCBCCCBCCCCCCBCCB...

หากต้องการตรวจสอบให้เปลี่ยนบรรทัดที่ระบุในรหัสด้านล่างเพื่อเริ่มต้นที่ 2946 แทน 5 การยืนยันใช้เวลา 20 วินาที

อัพเดท: โปรแกรมที่ได้รับการปรับปรุง โปรแกรมเก่าค้นหาสถานที่มากกว่า ~ 10x

เวอร์ชั่นใหม่ค้นหาได้CCCCCCใน 33 นาทีเท่านั้น

วิธีการทำงานของรหัส: โดยทั่วไปฉันดูเฉพาะภูมิภาคที่ตรงกับส่วนท้ายของสตริงที่เพิ่มขึ้นและคำนวณตัวอักษรโดยดู recursively กลับไปที่สตริงเดิม โปรดทราบว่ามันใช้ตารางบันทึกซึ่งอาจเติมหน่วยความจำของคุณ วางหมวกลงบนความยาวของตารางบันทึกหากจำเป็น

import time
import sys
sys.setrecursionlimit(4000)
ULIMIT=4000
end_positions=[]
current_end=2
while len(end_positions)<ULIMIT+3:
    end_positions.append(current_end)
    next_end=((current_end+1)*3+1)//2-1
    current_end=next_end
memo={}
def find_letter(pos):
    if pos in memo:
        return memo[pos]
    if pos<3:
        return 'ABC'[pos]
    for end_num in range(len(end_positions)-1):
        if pos>end_positions[end_num] and pos<=end_positions[end_num+1]:
            delta=end_positions[end_num+1]-end_positions[end_num]
            if len(memo)>5*10**6:
                return find_letter(pos-delta)
            memo[pos]=find_letter(pos-delta)
            return memo[pos]
time.clock()
for end_num in range(5,ULIMIT+1): # This line.
    diff = 1 # Because end_num is guaranteed to be a C
    while True:
        last_letter=find_letter(end_positions[end_num]+diff)
        if not last_letter=='C':
            break
        diff+=1
    if end_num%100==0:
        pos_str=str(end_positions[end_num])
        print(end_num,'%s.%s*10^%i'%(pos_str[0],pos_str[1:5],len(pos_str)-1),
        len(memo),diff,time.clock())
    if diff>=6:
        print(end_num,end_positions[end_num],diff,time.clock())

จำนวนสูงสุดปัจจุบันค้นหา: 4000 ซ้ำ

CCCCCC พบได้ที่ซ้ำ: 2946


นี่คืองูหลามใช่มั้ย
งานอดิเรกของ Calvin

ใช่ฉันจะเพิ่มที่
isaacg

(+1) โปรแกรมของคุณด้วยsys.setrecursionlimit(4000)และ ULIMIT=4000พบ (ในระบบของฉันประมาณ 3.5 ชั่วโมง) การเกิดขึ้นครั้งแรกของ CCCCCC ที่ index = 2.124 * 10 ^ 519 ดัชนีที่แน่นอนอยู่ในความคิดเห็นถัดไป ...
res

3
2124002227156710537549582070283786072301315855169987260450819829164756027922998360364044010386660076550764749849261595395734745608255162468143483136030403857241667604197146133343367628903022619551535534430377929831860918493875279894519909944379122620704864579366098015086419629439009415947634870592393974557860358412680068086381231577773140182376767811142988329838752964017382641454691037714240414750501535213021638601291385412206075763857490254382670426605045419312312880204888045665938646319068208885093114686859061215
res

! น่ากลัว ฉันไม่เคยสงสัยเลยว่ามันจะประสบความสำเร็จ
isaacg

12

CCCCCC พบได้ที่ 2.124 * 10 ^ 519

CCCCCCรหัสทับทิมต่อไปนี้ถูกใช้ในการค้นหา

SEARCH = 6

k = [5,3]

getc=->i{
  j=i
  k.unshift(k[0]+(k[0]+1)/2)while(k[0]<=j)
  k.each_cons(2){|f,g|j-=f-g if j>=g}
  "ABC"[j]
}

while true
  x=k[0]
  x-=1 while getc[x]=="C"
  x+=1 
  l=1
  l+=1 while getc[x+l]=="C"

  break if l>=SEARCH
end

puts x
puts (x-14..x+l+13).map{|i|getc[i]}*""

ดัชนีเป็นเช่นเดียวกับในคำตอบของ@isaacg

รันไทม์ของรหัสข้างต้นสำหรับ 6 อยู่ในลำดับของสิบวินาทีบนคอมพิวเตอร์ของฉัน อย่างไรก็ตามมันยังคงค้นหาคำตอบสำหรับCCCCCCC(ถ้าคุณต้องการลองด้วยตัวเองตั้งค่าคงSEARCHที่7)

คุณสามารถใช้getcเพื่อค้นหาตัวละครในตำแหน่งที่เฉพาะเจาะจงiซึ่งจะทำในบรรทัดสุดท้ายที่มีการพิมพ์สตริงรอบดัชนี


เร่งงานที่ดีขึ้น - วิธีการแก้ปัญหาของฉันเป็นอย่างมากที่หยาบและข้าวกล้อง
isaacg

สิ่งที่แปลก: ฉันใช้งานโค้ดด้านบนจนถึงการทำซ้ำ # 34000 หลังจากลบตัวแบ่งและเปลี่ยนการทดสอบประมาณเล็กน้อยและพบเพียงการรันครั้งเดียวของ 6 นี่เป็นปัญหาของรหัส (ฉันสงสัย) หรือ มันเป็นเพียงสถานที่ให้บริการที่แปลกของลำดับ?
isaacg

@isaacg โปรดทราบว่าเราจะตรวจสอบการแบ่งของแต่ละลำดับเท่านั้นและทำให้พลาดลำดับการคัดลอกทั้งหมด C ^ 6 เมื่อถึงเวลาพักเหล่านั้นดูเหมือนจะหายากมาก - ดังนั้นฉันคิดว่าเราจะไม่เห็น C ^ 7 ในเร็ว ๆ นี้
ฮาวเวิร์ด

ฉันรู้ แต่เนื่องจากพบว่ามีตัวแบ่งลำดับหลังจากมีการทำซ้ำเพียง 2,946 ครั้งฉันคาดว่าจะเห็นตัวที่สองโดยการวนซ้ำ 40000 ซึ่งเป็นที่ที่ฉันอยู่ตอนนี้
isaacg

@isaacg คุณอาจจะใช้รหัส (มากได้เร็วขึ้นมาก) ที่นี่: ideone.com/HoEKOB แม้ว่าฉันจะไม่สามารถหา C ^ 6 อีกตัวที่จุดลำดับ (แม้แต่น้อยกว่า C ^ 7)
ฮาวเวิร์ด

5

(ไม่ตอบ แต่ยาวเกินไปสำหรับความคิดเห็น.)

ต่อไปนี้คือการแปล Python ของโปรแกรม Rubyของ@ Howard (เร่งความเร็วด้วยปัจจัยที่อยู่ใกล้ 3 โดยมีเพียงหนึ่งรายการgetcในลูปการค้นหา) ในระบบของฉันสิ่งนี้จะค้นหา C ^ 6 ตัวแรกใน 3 วินาที ใน 93 ชั่วโมงก็ไม่พบ C ^ 7 231,000 ซ้ำดังนั้น C แรก ^ 7 (ถ้ามี) จะต้องเกิดขึ้นหลังจากที่ทางด้านซ้ายสุด 10 ^ 40,677 ตำแหน่งในสตริงไม่มีที่สิ้นสุด

import time

L = [5, 3]      #list grows "backwards" (by insertion on the left)

def getc(i):    #return the letter at index i
    while L[0] <= i: L.insert(0,L[0] + (L[0] + 1)//2)
    for k in range(len(L)-1): 
        if i >= L[k+1]: i -= L[k] - L[k+1]
    return 'abc'[i]

def search(k):  #find the first occurrence of c^k
    start = time.time()
    iter = 0
    while True:
        iter += 1
        if iter % 1000 == 0: print iter, time.time()-start
        p = L[0] - 1
        l = 1
        while getc(p+l)=='c': l += 1
        if l == k: break 
    return p, iter, time.time()-start

k = 6

(indx, iter, extime) = search(k)
print 'run length:', k
print 'index:', indx, '    (',len(str(indx)),'digits )'
print 'iteration count:', iter
print 'neighborhood:', ''.join([getc(i) for i in range(indx-1,indx+k+10)])
print 'execution time:', extime

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