Wo sind die Läufe in dieser unendlichen Zeichenfolge? (CCCCCC gefunden!)

25

ABCBetrachten Sie beginnend mit der Zeichenfolge das Ergebnis des wiederholten Anhängens der letzten Hälfte an sich selbst (verwenden Sie die größere Hälfte, wenn die Länge ungerade ist).

Wir bekommen den Fortschritt:

ABC
ABCBC
ABCBCCBC
ABCBCCBCCCBC
ABCBCCBCCCBCBCCCBC
etc...

Stellen Sie Sdie resultierende unendliche Zeichenfolge (oder Sequenz) dar, die sich ergibt, wenn dieser Vorgang für immer wiederholt wird.

Tor

Das Ziel dieser Code-Abfrage ist es, den Index des ersten Auftretens von Läufen von C's in zu finden S.

Zuerst ist es einfach: Ctritt zuerst am Index 2, CCam 4, CCCam 7, CCCCam auf 26, aber CCCCCist vollständig am Index 27308! Danach geht mir das Gedächtnis aus.

Der Gewinner ist der Beitrag, der die meisten Laufindizes korrekt generiert (in der Reihenfolge beginnend mit C). Sie können einen beliebigen Algorithmus verwenden, müssen ihn jedoch erklären, wenn Sie keine grundlegende Brute-Force-Methode verwenden. Die Ein- und Ausgabe kann in jedem leicht verständlichen Format erfolgen.

Wichtiger Hinweis: Ich weiß offiziell nicht, ob Statsächlich alle Läufe von C's enthalten sind. Diese Frage leitet sich von dieser an der Mathematics Stack Exchange ab , in der der Autor auch nichts gefunden hat CCCCCC. Ich bin gespannt, ob hier jemand kann. (Diese Frage basiert wiederum auf meiner ursprünglichen Frage zum Thema .)

Wenn Sie nachweisen können, dass nicht alle Läufe von in Cauftreten S, gewinnen Sie automatisch, da diese Frage nicht mehr gültig ist. Wenn niemand dies beweisen oder finden kann, CCCCCCist der Gewinner die Person, die die höchste Untergrenze für den Index von CCCCCC(oder was auch immer der größte ungelöste Lauf ist, wenn CCCCCCgefunden wird) erhalten kann.

Update: Ein großes Lob an Isaacs und Res , die CCCCCCbei dem astronomischen Index von 2,124 * 10 ^ 519 gefunden haben. Bei dieser Geschwindigkeit kann ich mir nicht vorstellen, CCCCCCCmit einer Methode zu finden, die auf roher Gewalt beruht. Gute Arbeit Jungs!

Calvins Hobbys
quelle
Ich verstehe es nicht - Sie sagen, Sie haben es CCCCCbei Index 27308 gefunden, aber später hört es sich so an, als ob Sie nicht wissen, wo es zuerst auftritt. Meinten Sie CCCCCC?
Isaacg
@isaacg Ups. 6 C ist derjenige, der schwer zu finden ist. Ich werde das reparieren.
Calvins Hobbys
Wenn die Vermutung falsch ist, gibt es ein N, für das c ^ N die längste Laufzeit ist. Ich bin mir ziemlich sicher, dass es möglich sein sollte, eine längere Sequenz zu konstruieren, die zu einem Widerspruch führt und die Vermutung bestätigt. Ich glaube auch nicht, dass es zu schwer ist, aber andererseits können Probleme leicht unterschätzt werden ...
Ingo Bürk
Ich komme auf jeden Fall um Mitternacht mit meinem neuen Stimmzettel hierher zurück - sowohl für die Frage als auch für die Antworten!
Trichoplax
Für diejenigen, die suchen, kann dies etwas einfacher sein: Wenn Sie das erste "A" entfernen, müssen Sie nur mit "AB" spielen und die Hälfte + 1 für die nächste Iteration anhängen.
Faquarl

Antworten:

23

Gefunden bei 2.124 * 10 ^ 519.

Präzises Index ist 2124002227156710537549582070283786072301315855169987260450819829164756027922998360364044010386660076550764749849261595395734745608255162468143483136030403857241667604197146133343367628903022619551535534430377929831860918493875279894519909944379122620704864579366098015086419629439009415947634870592393974557860358412680068086381231577773140182376767811142988329838752964017382641454691037714240414750501535213021638601291385412206075763857490254382670426605045419312312880204888045665938646319068208885093114686859061215

Nach 3,5-stündiger Suche von res mit dem unten stehenden (alten) Code gefunden.

Um diesen Index herum lautet die Zeichenfolge: ...BCCBCBCCCBCCCCCCBCCB...

Ändern Sie zur Überprüfung die angezeigte Zeile im folgenden Code so, dass sie bei 2946 anstatt bei 5 beginnt. Die Überprüfung dauert 20 Sekunden.

Update: Verbessertes Programm. Das alte Programm hat ~ 10x mehr Stellen als nötig durchsucht.

Neue Version findet das CCCCCCin nur 33 Minuten.

So funktioniert der Code: Grundsätzlich betrachte ich nur die Bereiche, die den Enden inkrementeller Zeichenfolgen entsprechen, und berechne die Buchstaben, indem ich rekursiv auf die ursprüngliche Zeichenfolge zurückblicke. Beachten Sie, dass eine Memo-Tabelle verwendet wird, die Ihren Speicher füllen kann. Setzen Sie bei Bedarf eine Kappe auf die Länge des Memotisches.

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

Aktuell max. Gesucht nach: 4000 Iterationen

CCCCCC gefunden bei Iteration (en): 2946

isaacg
quelle
Das ist Python, oder?
Calvins Hobbys
Ja, das werde ich hinzufügen.
Isaacg
(+1) Ihr Programm hat mit sys.setrecursionlimit(4000)und ULIMIT=4000(in ungefähr 3,5 Stunden auf meinem System) das erste Vorkommen von CCCCCC bei index = 2.124 * 10 ^ 519 gefunden. Der genaue Index steht im nächsten Kommentar ...
res
3
2124002227156710537549582070283786072301315855169987260450819829164756027922998360364044010386660076550764749849261595395734745608255162468143483136030403857241667604197146133343367628903022619551535534430377929831860918493875279894519909944379122620704864579366098015086419629439009415947634870592393974557860358412680068086381231577773140182376767811142988329838752964017382641454691037714240414750501535213021638601291385412206075763857490254382670426605045419312312880204888045665938646319068208885093114686859061215
res
Genial! Ich hätte nie gedacht, dass es so kurz vor dem Erfolg steht.
isaacg
12

Gefunden bei 2.124 * 10 ^ 519.

Der folgende Ruby-Code wurde für die Suche verwendet 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]}*""

Der Index ist der gleiche wie in der Antwort von @isaacg .

Die Laufzeit des obigen Codes für 6 liegt auf meinem Computer in der Größenordnung von zehn Sekunden. Trotzdem ist es immer noch auf der Suche nach einer Antwort CCCCCCC(wenn du es selbst ausprobieren willst, setze die Konstante SEARCHauf 7).

Sie können getcdas Zeichen an einer bestimmten Position suchen, iwie dies in der letzten Zeile der Fall ist, in der die Zeichenfolge um den Index gedruckt wird.

Howard
quelle
Gute Arbeit, die es beschleunigt - meine Lösung war sehr rau und unpoliert.
Isaacg
Etwas seltsames: Ich habe den obigen Code bis zur Iteration # 34000 ausgeführt, nachdem ich die Unterbrechung entfernt und die Tests ein wenig geändert habe, und es wird nur der eine Durchlauf von 6 gefunden. Ist dies ein Problem mit dem Code (ich bezweifle es) oder ist es nur eine seltsame Eigenschaft der Sequenz?
isaacg
@isaacg Beachten Sie, dass wir nur die Unterbrechungen jeder Sequenz überprüfen und daher alle Kopiersequenzen C ^ 6 verpassen. In den Pausen scheinen diese sehr selten zu sein - daher denke ich, dass wir bald kein C ^ 7 sehen werden.
Howard
Ich weiß, aber da einer nach nur 2946 Iterationen bei einer Sequenzunterbrechung gefunden wurde, würde ich erwarten, einen zweiten mit 40000 Iterationen zu sehen, wo ich jetzt bin.
Isaacg
@isaacg Sie können den (viel schnelleren) Code hier verwenden: ideone.com/HoEKOB . Trotzdem konnte ich an einem Sequenzpunkt kein anderes C ^ 6 finden (noch weniger ein C ^ 7).
Howard
5

(Keine Antwort, aber zu lang für einen Kommentar.)

Das Folgende ist eine Python-Übersetzung von @ Howards Ruby-Programm (beschleunigt um einen Faktor nahe 3, indem nur einer getcin der Suchschleife vorhanden ist). Auf meinem System findet dies das erste C ^ 6 in 3 Sekunden. In 93 Stunden wird in 231.000 Iterationen kein C ^ 7 gefunden, daher muss das erste C ^ 7 (falls vorhanden) nach den am weitesten links stehenden 10 ^ 40677-Positionen in der unendlichen Zeichenfolge auftreten.

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
quelle
Mit PyPy findet es C ^ 6 in weniger als einer Sekunde auf meinem Computer.
Dennis