Di mana deretan dalam string tak terbatas ini? (Ditemukan!)

25

Dimulai dengan string ABC, pertimbangkan hasil berulang kali menambahkan bagian terakhir dari dirinya sendiri (menggunakan bagian yang lebih besar jika panjangnya aneh).

Kami mendapatkan perkembangan:

ABC
ABCBC
ABCBCCBC
ABCBCCBCCCBC
ABCBCCBCCCBCBCCCBC
etc...

Biarkan Smewakili string tak terbatas yang dihasilkan (atau urutan) yang dihasilkan karena prosedur ini diulang selamanya.

Tujuan

Tujuan dalam tantangan kode ini adalah untuk menemukan indeks kemunculan pertama kali proses Cdi S.

Awalnya gampang: Cpertama kali terjadi pada index 2, CCat 4, CCCat 7, CCCCat 26, tetapi CCCCCsudah pasti indeks 27308! Setelah itu ingatanku habis.

Pemenangnya adalah pengiriman yang benar menghasilkan indeks paling banyak dijalankan (dalam urutan, mulai dari C). Anda dapat menggunakan segala jenis algoritma tetapi pastikan untuk menjelaskannya jika Anda tidak menggunakan kekuatan kasar dasar. Input dan output dapat dalam format yang mudah dimengerti.

Catatan Penting: Saya tidak secara resmi tahu apakah Sbenar-benar berisi semua proses C. Pertanyaan ini berasal dari yang ini di Pertukaran Matematika , di mana penulis belum menemukan CCCCCCkeduanya. Saya ingin tahu apakah ada orang di sini yang bisa. (Pertanyaan itu pada gilirannya berdasarkan pertanyaan awal saya pada topik .)

Jika Anda dapat membuktikan bahwa tidak semua proses Cterjadi Smaka Anda akan menang secara otomatis karena pertanyaan ini tidak lagi valid. Jika tidak ada yang bisa membuktikan itu atau menemukan CCCCCCmaka pemenangnya adalah orang yang bisa mendapatkan batas bawah tertinggi pada indeks CCCCCC(atau apa pun yang tidak terpecahkan adalah jika CCCCCCditemukan).

Pembaruan: pujian besar untuk isaacg dan res yang ditemukan CCCCCCpada indeks astronomi 2.124 * 10 ^ 519. Pada tingkat ini aku tidak bisa membayangkan menemukan CCCCCCCdengan metode apa pun yang bergantung pada kekerasan. Kerja bagus kawan!

Hobi Calvin
sumber
Saya tidak mengerti - Anda mengatakan Anda sudah menemukan CCCCCdi indeks 27308, tetapi nanti sepertinya Anda tidak tahu di mana itu pertama kali terjadi. Apakah maksud Anda CCCCCC?
isaacg
@isaacg Ups. 6 C adalah yang sulit ditemukan. Saya akan memperbaikinya.
Hobi Calvin
Jika dugaan itu salah, ada N yang c ^ N adalah jangka panjang. Saya cukup yakin seharusnya bisa membangun urutan yang lebih lama, mengarah ke kontradiksi dan membuktikan dugaan tersebut. Saya juga tidak berpikir itu terlalu sulit, tetapi di sisi lain masalah dapat dengan mudah diremehkan ...
Ingo Bürk
Saya pasti akan kembali ke sini di tengah malam dengan suara baru - untuk pertanyaan dan jawaban!
trichoplax
Bagi mereka yang mencari, ini bisa membuatnya sedikit lebih mudah: Jika Anda menghapus "A" pertama maka Anda hanya perlu bermain dengan "AB" dan Anda menambahkan setengah +1 untuk iterasi berikutnya.
Faquarl

Jawaban:

23

CCCCCC ditemukan di 2.124 * 10 ^ 519.

Indeks Precise adalah 2124002227156710537549582070283786072301315855169987260450819829164756027922998360364044010386660076550764749849261595395734745608255162468143483136030403857241667604197146133343367628903022619551535534430377929831860918493875279894519909944379122620704864579366098015086419629439009415947634870592393974557860358412680068086381231577773140182376767811142988329838752964017382641454691037714240414750501535213021638601291385412206075763857490254382670426605045419312312880204888045665938646319068208885093114686859061215

Ditemukan oleh res, menggunakan kode (versi lama) di bawah, setelah 3,5 jam pencarian.

Di sekitar indeks itu, stringnya adalah: ...BCCBCBCCCBCCCCCCBCCB...

Untuk memverifikasi, ubah baris yang ditunjukkan dalam kode di bawah ini untuk mulai pada 2946, bukan 5. Verifikasi membutuhkan 20 detik.

Pembaruan: Program yang ditingkatkan. Program lama mencari ~ 10x lebih banyak lokasi daripada yang diperlukan.

Versi baru menemukan CCCCCChanya dalam 33 menit.

Cara kode bekerja: Pada dasarnya, saya hanya melihat daerah yang sesuai dengan ujung string tambahan, dan menghitung huruf dengan melihat secara rekursif kembali ke string asli. Perhatikan bahwa ia menggunakan tabel memo, yang dapat mengisi memori Anda. Letakkan penutup pada panjang meja memo jika perlu.

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

Maks saat ini dicari ke: 4000 iterasi

CCCCCC ditemukan di iterasi: 2946

isaacg
sumber
Ini Python, kan?
Hobi Calvin
Ya, saya akan menambahkannya.
isaacg
(+1) Program Anda, dengan sys.setrecursionlimit(4000)dan ULIMIT=4000, menemukan (dalam sekitar 3,5 jam pada sistem saya) kemunculan pertama dari CS pada indeks = 2.124 * 10 ^ 519. Indeks persisnya ada di komentar berikutnya ...
res
3
2124002227156710537549582070283786072301315855169987260450819829164756027922998360364044010386660076550764749849261595395734745608255162468143483136030403857241667604197146133343367628903022619551535534430377929831860918493875279894519909944379122620704864579366098015086419629439009415947634870592393974557860358412680068086381231577773140182376767811142988329838752964017382641454691037714240414750501535213021638601291385412206075763857490254382670426605045419312312880204888045665938646319068208885093114686859061215
res
Luar biasa! Saya tidak pernah curiga bahwa ini hampir berhasil.
isaacg
12

CCCCCC ditemukan di 2.124 * 10 ^ 519.

Kode ruby ​​berikut digunakan untuk mencari 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]}*""

Indeksnya sama dengan jawaban @isaacg .

Runtime dari kode di atas untuk 6 dalam urutan sepuluh detik di komputer saya. Namun demikian, masih mencari jawaban untuk CCCCCCC(jika Anda ingin mencobanya sendiri tetapkan konstan SEARCHke 7).

Anda dapat menggunakan getcuntuk menemukan karakter pada posisi tertentu iseperti yang dilakukan pada baris terakhir di mana string di sekitar indeks dicetak.

Howard
sumber
Pekerjaan bagus mempercepatnya - solusi saya sangat kasar dan kasar.
isaacg
Sesuatu yang aneh: Saya sudah menjalankan kode di atas hingga iterasi # 34000 setelah menghapus istirahat dan mengubah tes sekitar sedikit, dan hanya menemukan satu run dari 6. Apakah ini masalah dengan kode (saya ragu) atau apakah itu hanya properti aneh dari urutan?
isaacg
@isaacg Perhatikan bahwa kita hanya memeriksa jeda setiap urutan dan dengan demikian melewatkan semua urutan salinan C ^ 6. Pada saat istirahat itu tampaknya sangat jarang - jadi saya pikir kita tidak akan melihat C ^ 7 segera.
Howard
Saya tahu, tetapi karena satu ditemukan pada urutan istirahat setelah hanya 2946 iterasi, saya berharap untuk melihat yang kedua dengan 40000 iterasi, yang mana saya sekarang.
isaacg
@isaacg Anda dapat menggunakan kode (jauh lebih cepat) di sini: ideone.com/HoEKOB . Bahkan dengan itu saya tidak dapat menemukan C ^ 6 lain pada titik urutan (bahkan kurang C ^ 7).
Howard
5

(Bukan jawaban, tapi terlalu lama untuk komentar.)

Berikut ini adalah terjemahan Python dari program @ Howard's Ruby (dipercepat oleh faktor dekat 3 dengan hanya memiliki satu getcdi loop pencarian). Di sistem saya, ini menemukan C ^ 6 pertama dalam 3 detik. Dalam 93 jam, ia tidak menemukan C ^ 7 dalam 231.000 iterasi, sehingga C ^ 7 pertama (jika ada) harus terjadi setelah posisi 10 ^ 40677 paling kiri dalam string tak terbatas.

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
res
sumber
Dengan PyPy, ia menemukan C ^ 6 dalam waktu kurang dari sedetik di mesin saya.
Dennis