Bu sonsuz dizede kaçamak nerede? (CCCCCC Bulundu!)


25

Dizeyle başlayarak ABC, kendisinin son yarısını tekrar tekrar eklemenin sonucunu düşünün (uzunluk tek ise büyük yarıyı kullanın).

İlerlemeyi alıyoruz:

ABC
ABCBC
ABCBCCBC
ABCBCCBCCCBC
ABCBCCBCCCBCBCCCBC
etc...

SBu prosedür sonsuza dek tekrar edildiğinde ortaya çıkan sonsuz dize (veya dizi) temsil edelim .

Hedef

Bu kod meydan amaç ishal ilk geçtiği dizinini bulmaktır Ciçinde s' S.

İlk başta kolaydır: Cilk önce endekste 2, CCat 4, CCCat 7, CCCCat 26, ancak CCCCCindeks yolunda olur 27308! Bundan sonra hafızam biter.

Kazanan, en fazla çalıştırma endeksini doğru şekilde üreten başvuru olacaktır (sırasıyla, başlayarak C). Herhangi bir algoritma kullanabilirsiniz, ancak temel kaba kuvvet kullanmıyorsanız açıkladığınızdan emin olun. Giriş ve çıkış, anlaşılması kolay bir formatta olabilir.

Önemli Not: Resmen Stüm yarışları içerip içermediğini resmi olarak bilmiyorum C. Bu soru, ondan yazarın da bulamadığı Matematik Yığın Değiş tokuşundan gelmektedirCCCCCC . Merak ediyorum ki burada biri olabilir. (Bu soru da konuyla ilgili orijinal soruma dayanıyor .)

Tüm olayların Cmeydana gelmediğini ispatlayabilirseniz, Sbu soru artık geçerli olmayacağından otomatik olarak kazanırsınız. Eğer kimse bunu kanıtlayamazsa veya bulamazsa CCCCCC, kazanan endeksinde en yüksek alt sınırı alabilecek kişi olacaktır CCCCCC(ya da en büyük çözülmemiş koşu ise ne olursa olsun CCCCCC).

Güncelleme: 2.124 * 10 ^ 519 astronomik indeksinde bulunan isaacg ve res Humongous kudos CCCCCC. Bu oranda CCCCCCCkaba kuvvete dayanan herhangi bir yöntemle bulmayı düşünemiyorum . İyi iş adamları!


Bilmiyorum - CCCCC27308 endeksinde bulduğunuzu söylüyorsunuz, ancak daha sonra ilk nerede olduğunu bilmiyormuşsunuz gibi geliyor. Bunu mu demek istediniz CCCCCC?
isaacg

@ isaacg Oops. 6 C bulmak zor olanıdır. Bunu düzelteceğim.
Calvin'in Hobileri

Eğer varsayım yanlışsa, c ^ N en uzun çalışma olan bir N vardır. Daha uzun bir sekans inşa etmenin mümkün olacağından oldukça eminim, bir çelişki doğurabilir ve varsayımı kanıtlayabiliriz. Ayrıca çok zor olduğunu sanmıyorum, ancak diğer yandan problemler kolayca hafife alınabiliyor ...
Ingo Bürk

Kesinlikle gece yarısı yeni bir oy grubumla geleceğim - hem soru hem de cevaplar için!
trichoplax

Arayanlar için bu biraz daha kolay olabilir: İlk "A" harfini kaldırırsanız, sadece "AB" ile oynamanız gerekir ve bir sonraki yineleme için yarım + 1 eklersiniz.
Faquarl

Yanıtlar:


23

CCCCCC, 2.124 * 10 ^ 519'da bulundu.

Hassas endeksi 2124002227156710537549582070283786072301315855169987260450819829164756027922998360364044010386660076550764749849261595395734745608255162468143483136030403857241667604197146133343367628903022619551535534430377929831860918493875279894519909944379122620704864579366098015086419629439009415947634870592393974557860358412680068086381231577773140182376767811142988329838752964017382641454691037714240414750501535213021638601291385412206075763857490254382670426605045419312312880204888045665938646319068208885093114686859061215 olduğunu

3.5 saatlik aramanın ardından, aşağıdaki (eski sürüm) kodunu kullanarak res tarafından bulunur.

Bu dizinin etrafında, dize: ...BCCBCBCCCBCCCCCCBCCB...

Doğrulamak için, 5 yerine, 2946'dan başlamak üzere aşağıdaki kodda belirtilen satırı değiştirin. Doğrulama 20 saniye sürer.

Güncelleme: Geliştirilmiş program. Eski program ~ gereğinden fazla 10 kat daha fazla yer aradı.

Yeni sürüm CCCCCCsadece 33 dakika içinde bulur .

Kodun işleyişi: Temel olarak, yalnızca artımlı dizgelerin uçlarına karşılık gelen bölgelere bakıyorum ve harfleri orijinal dizgeye tekrarlı olarak bakarak hesaplıyorum. Hafızanızı doldurabilecek bir not tablosu kullandığını unutmayın. Gerekirse not tablosunun uzunluğuna bir kapak yerleştirin.

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

Geçerli maksimum aradı: 4000 yineleme

CCCCCC yineleme (ler) da bulundu: 2946


Bu Python değil mi?
Calvin'in Hobileri

Evet, ekleyeceğim.
isaacg

(1) Programınız ile sys.setrecursionlimit(4000)ve ULIMIT=4000, endeks = 2,124 * 10 ^ 519 de CCCCCC ilk geçtiği (sistemimde 3.5 hakkında saat olarak) bulundu. Tam endeks bir sonraki yorumda ...
res

3
2124002227156710537549582070283786072301315855169987260450819829164756027922998360364044010386660076550764749849261595395734745608255162468143483136030403857241667604197146133343367628903022619551535534430377929831860918493875279894519909944379122620704864579366098015086419629439009415947634870592393974557860358412680068086381231577773140182376767811142988329838752964017382641454691037714240414750501535213021638601291385412206075763857490254382670426605045419312312880204888045665938646319068208885093114686859061215
res

Müthiş! Başarıya bu kadar yakın olduğundan hiç şüphem yoktu.
isaacg

12

CCCCCC, 2.124 * 10 ^ 519'da bulundu.

Aramak için aşağıdaki yakut kodu kullanıldı 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]}*""

Endeks @isaacg cevabı aynıdır .

6 için yukarıdaki kodun çalışma zamanı bilgisayarımda on saniye sırasıyla. Bununla birlikte, hala bir cevap arayışı içindedir CCCCCCC(eğer kendiniz sürekli SEARCHolarak denemek istiyorsanız 7).

getcKarakteri i, dizinin etrafındaki dizenin basıldığı son satırda olduğu gibi, belirli bir konumda bulmak için kullanabilirsiniz .


Hızlandırmak iyi iş - benim çözümüm çok kaba ve cilasızdı.
isaacg

Tuhaf bir şey: Yukarıdaki kodu, ara verdikten ve testleri bir parça değiştirdikten sonra # 34000 yinelemesine kadar çalıştırdım ve yalnızca 6 satırından birini bulur. Bu kodla ilgili bir sorun mu var? dizinin tek bir özelliği mi?
isaacg

@isaacg Yalnızca her dizinin sonlarını kontrol ettiğimizi ve bu nedenle tüm C ^ 6 kopya dizilerini özlediğimizi unutmayın. Ara verdiklerinde bunlar çok nadir görünüyor - bu yüzden yakında C ^ 7 görmeyeceğimizi düşünüyorum.
Howard,

Biliyorum, ancak yalnızca 2946 yinelemeden sonra bir dizi kopuşunda bulunduğundan, şimdi olduğum yer olan 40000 yinelemeyle ikinci bir tanesini görmeyi beklerdim.
isaacg

@isaacg Burada (çok daha hızlı) kodunu kullanabilirsiniz: ideone.com/HoEKOB . Buna rağmen bir sıralama noktasında başka bir C ^ 6 bulamadım (daha az bir C ^ 7).
Howard,

5

(Cevap değil, yorum yapmak için çok uzun.)

Aşağıdaki, Howard'ın Ruby programının bir Python çevirisidir ( getcarama döngüsünde sadece bir tane olmak üzere 3'e yakın bir faktör tarafından hızlandırılmıştır ). Sistemimde bu ilk C ^ 6'yı 3 saniyede bulur. 93 saat içinde 231.000 yinelemede C ^ 7 bulamaz, bu nedenle ilk C ^ 7 (varsa) sonsuz dizede en soldaki 10 ^ 40677 konumundan sonra gerçekleşmelidir.

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 ile makinemde bir saniyeden daha kısa sürede C ^ 6'yı bulur.
Dennis,
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.