¿Dónde están las corridas en esta cadena infinita? (¡Encontrado!)

25

Comenzando con la cadena ABC, considere el resultado de agregar repetidamente la última mitad de sí mismo (usando la mitad más grande si la longitud es impar).

Obtenemos la progresión:

ABC
ABCBC
ABCBCCBC
ABCBCCBCCCBC
ABCBCCBCCCBCBCCCBC
etc...

Supongamos que Srepresenta la secuencia (o secuencia) infinita resultante que se produce cuando este procedimiento se repite para siempre.

Gol

El objetivo en este desafío de código es encontrar el índice de la primera aparición de corridas de C's en S.

Al principio es fácil: Cprimero ocurre en el índice 2, CCen 4, CCCen 7, CCCCen 26, ¡pero CCCCCestá en el índice 27308! Después de eso se me acaba la memoria.

El ganador será el envío que genere correctamente la mayoría de los índices de ejecución (en orden, comenzando en C). Puede usar cualquier tipo de algoritmo, pero asegúrese de explicarlo si no está usando la fuerza bruta básica. La entrada y la salida pueden estar en cualquier formato fácil de entender.

Nota importante: No sé oficialmente si Scontiene o no todas las ejecuciones de C's. Esta pregunta se deriva de esta en el Mathematics Stack Exchange , en el que el autor tampoco ha encontrado CCCCCC. Tengo curiosidad si alguien aquí puede. (Esa pregunta a su vez se basa en mi pregunta original sobre el tema ).

Si puede demostrar que no se Cproducen todas las corridas S, ganará automáticamente ya que esta pregunta ya no será válida. Si nadie puede probar eso ni encontrarlo, CCCCCCentonces el ganador será la persona que pueda obtener el límite inferior más alto en el índice de CCCCCC(o cualquiera que sea la carrera sin resolver más grande si CCCCCCse encuentra).

Actualización: Felicitaciones a isaacg y res que han encontrado CCCCCCen el índice astronómico de 2.124 * 10 ^ 519. A este ritmo, no puedo imaginar encontrar CCCCCCCcon ningún método que se base en la fuerza bruta. Buen trabajo chicos!

Pasatiempos de Calvin
fuente
No lo entiendo: estás diciendo que has encontrado CCCCCen el índice 27308, pero luego parece que no sabes dónde ocurre por primera vez. Quiso decir CCCCCC?
isaacg
@isaacg Vaya. 6 C es el que es difícil de encontrar. Lo arreglaré
Aficiones de Calvin
Si la conjetura es incorrecta, hay una N para la cual c ^ N es la ejecución más larga. Estoy bastante seguro de que debería ser posible construir una secuencia más larga, conduciendo a una contradicción y demostrando la conjetura. Tampoco creo que sea demasiado difícil, pero por otro lado, los problemas pueden subestimarse fácilmente ...
Ingo Bürk
Definitivamente regresaré aquí a medianoche con mi nuevo lote de votos, ¡tanto para la pregunta como para las respuestas!
trichoplax
Para aquellos que están buscando, esto puede hacer que sea un poco más fácil: si elimina la primera "A", entonces solo tendrá que jugar con "AB" y agregará la mitad + 1 para la próxima iteración.
Faquarl

Respuestas:

23

CCCCCC encontrado en 2.124 * 10 ^ 519.

Índice precisa es 2124002227156710537549582070283786072301315855169987260450819829164756027922998360364044010386660076550764749849261595395734745608255162468143483136030403857241667604197146133343367628903022619551535534430377929831860918493875279894519909944379122620704864579366098015086419629439009415947634870592393974557860358412680068086381231577773140182376767811142988329838752964017382641454691037714240414750501535213021638601291385412206075763857490254382670426605045419312312880204888045665938646319068208885093114686859061215

Encontrado por res, utilizando el código (versión anterior de) a continuación, después de 3,5 horas de búsqueda.

Alrededor de ese índice, la cadena es: ...BCCBCBCCCBCCCCCCBCCB...

Para verificar, cambie la línea indicada en el código a continuación para comenzar en 2946, en lugar de 5. La verificación lleva 20 segundos.

Actualización: programa mejorado. El programa anterior buscó ~ 10 veces más ubicaciones de las necesarias.

La nueva versión encuentra la CCCCCCen solo 33 minutos.

Cómo funciona el código: Básicamente, solo miro las regiones que corresponden a los extremos de las cadenas incrementales, y calculo las letras mirando recursivamente la cadena original. Tenga en cuenta que utiliza una tabla de notas, que puede llenar su memoria. Ponga una tapa en la longitud de la tabla de notas si es necesario.

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

Máximo actual buscado a: 4000 iteraciones

CCCCCC encontrado en la iteración (es): 2946

isaacg
fuente
Esto es Python ¿verdad?
Aficiones de Calvin
Sí, agregaré eso.
isaacg
(+1) Su programa, con sys.setrecursionlimit(4000)y ULIMIT=4000, encontró (en aproximadamente 3.5 horas en mi sistema) la primera aparición de CCCCCC en el índice = 2.124 * 10 ^ 519. El índice exacto está en el próximo comentario ...
res
3
2124002227156710537549582070283786072301315855169987260450819829164756027922998360364044010386660076550764749849261595395734745608255162468143483136030403857241667604197146133343367628903022619551535534430377929831860918493875279894519909944379122620704864579366098015086419629439009415947634870592393974557860358412680068086381231577773140182376767811142988329838752964017382641454691037714240414750501535213021638601291385412206075763857490254382670426605045419312312880204888045665938646319068208885093114686859061215
res
¡Increíble! Nunca sospeché que estaba tan cerca de tener éxito.
isaacg
12

CCCCCC encontrado en 2.124 * 10 ^ 519.

Se utilizó el siguiente código ruby ​​para buscar 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]}*""

El índice es el mismo que en la respuesta de @isaacg .

El tiempo de ejecución del código anterior para 6 es del orden de diez segundos en mi computadora. Sin embargo, todavía está buscando una respuesta para CCCCCCC(si desea probarlo, establezca constante SEARCHen 7).

Puede usar getcpara encontrar el carácter en una posición específica, iya que se hace en la última línea donde se imprime la cadena alrededor del índice.

Howard
fuente
Buen trabajo acelerándolo: mi solución fue muy dura y sin pulir.
isaacg
Algo extraño: ejecuté el código anterior hasta la iteración # 34000 después de eliminar el corte y cambiar las pruebas un poco, y solo encuentra la ejecución de 6. ¿Es este un problema con el código (lo dudo) o ¿Es solo una propiedad extraña de la secuencia?
isaacg
@isaacg Tenga en cuenta que solo verificamos los saltos de cada secuencia y, por lo tanto, omitimos todas las secuencias de copia C ^ 6. En los descansos, eso parece ser muy raro, por lo que creo que no veremos un C ^ 7 pronto.
Howard
Lo sé, pero dado que se encontró uno en un salto de secuencia después de solo 2946 iteraciones, esperaría ver un segundo por 40000 iteraciones, que es donde estoy ahora.
isaacg
@isaacg Puede usar el código (mucho más rápido) aquí: ideone.com/HoEKOB . Incluso con eso no pude encontrar otro C ^ 6 en un punto de secuencia (incluso menos un C ^ 7).
Howard
5

(No es una respuesta, pero es demasiado larga para un comentario).

La siguiente es una traducción de Python del programa Ruby de @ Howard (acelerado por un factor cercano a 3 al tener solo uno getcen el ciclo de búsqueda). En mi sistema, esto encuentra el primer C ^ 6 en 3 segundos. En 93 horas, no encuentra C ^ 7 en 231,000 iteraciones, por lo que el primer C ^ 7 (si existe) debe ocurrir después de las 10 ^ 40677 posiciones más a la izquierda en la cadena infinita.

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
fuente
Con PyPy, encuentra C ^ 6 en menos de un segundo en mi máquina.
Dennis