Onde estão as execuções nessa sequência infinita? (CCCCCC encontrado!)

25

Começando com a sequência ABC, considere o resultado de anexar repetidamente a última metade de si mesma (usando a metade maior se o comprimento for ímpar).

Temos a progressão:

ABC
ABCBC
ABCBCCBC
ABCBCCBCCCBC
ABCBCCBCCCBCBCCCBC
etc...

Vamos Srepresentar a sequência (ou sequência) infinita resultante que resulta como esse procedimento é repetido para sempre.

Objetivo

O objetivo neste desafio de código é encontrar o índice da primeira ocorrência de execuções de C's in S.

É fácil no começo: Cocorre primeiro no índice 2, CCem 4, CCCem 7, CCCCem 26, mas CCCCCé todo o caminho no índice 27308! Depois disso, minha memória se esgota.

O vencedor será o envio que gerar corretamente os índices mais executados (em ordem, começando em C). Você pode usar qualquer tipo de algoritmo, mas não se esqueça de explicá-lo se não estiver usando força bruta básica. A entrada e a saída podem estar em qualquer formato fácil de entender.

Nota importante: Não sei oficialmente se Scontém ou não todas as execuções C. Essa questão é derivada dessa pergunta no Mathematics Stack Exchange , na qual o autor também não encontrou CCCCCC. Estou curioso para saber se alguém aqui pode. (Essa pergunta, por sua vez, é baseada na minha pergunta original sobre o assunto .)

Se você puder provar que nem todas as execuções Cocorrem S, você vencerá automaticamente, pois essa pergunta não será mais válida. Se ninguém puder provar isso nem encontrar CCCCCC, o vencedor será a pessoa que conseguirá o limite inferior mais alto no índice de CCCCCC(ou qualquer que seja a maior execução não resolvida, se CCCCCCfor encontrada).

Atualização: Muitos elogios para isaacg e res que encontraram CCCCCCno índice astronômico de 2.124 * 10 ^ 519. Nesse ritmo, não consigo imaginar encontrar CCCCCCCum método que dependa da força bruta. Bom trabalho pessoal!

Passatempos de Calvin
fonte
Não entendi - você está dizendo que encontrou CCCCCno índice 27308, mas depois parece que não sabe onde ocorre pela primeira vez. Você quis dizer CCCCCC?
Isaacg
@isaacg Oops. 6 C's é o difícil de encontrar. Eu vou consertar isso.
Hobbies de Calvin
Se a conjectura estiver errada, existe um N para o qual c ^ N é o mais longo. Tenho certeza de que deve ser possível construir uma sequência mais longa, levando a uma contradição e comprovando a conjectura. Eu também não acho que é muito difícil, mas em outros problemas de mão pode facilmente subestimado ...
Ingo Bürk
Definitivamente, volto aqui à meia-noite com meu novo lote de votos - tanto para a pergunta quanto para as respostas!
Trichoplax
Para quem está pesquisando, isso pode facilitar um pouco: se você remover o primeiro "A", precisará tocar apenas com "AB" e acrescentar meia + 1 para a próxima iteração.
Faquarl

Respostas:

23

Encontrado em 2,124 * 10 ^ 519.

índice é preciso 2124002227156710537549582070283786072301315855169987260450819829164756027922998360364044010386660076550764749849261595395734745608255162468143483136030403857241667604197146133343367628903022619551535534430377929831860918493875279894519909944379122620704864579366098015086419629439009415947634870592393974557860358412680068086381231577773140182376767811142988329838752964017382641454691037714240414750501535213021638601291385412206075763857490254382670426605045419312312880204888045665938646319068208885093114686859061215

Encontrado por res, usando o código (versão antiga) abaixo, após 3,5 horas de pesquisa.

Em torno desse índice, a sequência é: ...BCCBCBCCCBCCCCCCBCCB...

Para verificar, altere a linha indicada no código abaixo para iniciar em 2946, em vez de 5. A verificação leva 20 segundos.

Atualização: Programa aprimorado. O programa antigo pesquisou ~ 10x mais locais do que o necessário.

Nova versão encontra o CCCCCCem apenas 33 minutos.

Como o código funciona: Basicamente, apenas olho para as regiões que correspondem às extremidades das seqüências incrementais e calculo as letras olhando recursivamente para a sequência original. Observe que ele usa uma tabela de notas, que pode encher sua memória. Coloque uma tampa no comprimento da tabela de notas, se necessário.

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 atual pesquisado para: 4000 iterações

CCCCCC encontrado na (s) iteração (ões): 2946

isaacg
fonte
Isso é Python, certo?
Passatempos de Calvin
Sim, eu vou adicionar isso.
Isaacg
(+1) Seu programa, com sys.setrecursionlimit(4000)e ULIMIT=4000, encontrou (em cerca de 3,5 horas no meu sistema) a primeira ocorrência de CCCCCC no índice = 2,124 * 10 ^ 519. O índice exato está no próximo comentário ...
res
3
2124002227156710537549582070283786072301315855169987260450819829164756027922998360364044010386660076550764749849261595395734745608255162468143483136030403857241667604197146133343367628903022619551535534430377929831860918493875279894519909944379122620704864579366098015086419629439009415947634870592393974557860358412680068086381231577773140182376767811142988329838752964017382641454691037714240414750501535213021638601291385412206075763857490254382670426605045419312312880204888045665938646319068208885093114686859061215
res
Impressionante! Eu nunca suspeitei que fosse tão perto de ter sucesso.
Isaacg
12

Encontrado em 2,124 * 10 ^ 519.

O seguinte código ruby ​​foi usado para procurar 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]}*""

O índice é o mesmo da resposta de @isaacg .

O tempo de execução do código acima para 6 é da ordem de dez segundos no meu computador. No entanto, ainda é possível procurar uma resposta CCCCCCC(se você quiser tentar definir constantemente SEARCHcomo 7).

Você pode usar getcpara encontrar o caractere em uma posição específica, icomo é feito na última linha em que a cadeia de caracteres ao redor do índice é impressa.

Howard
fonte
Bom trabalho acelerando - minha solução era muito áspera e polida.
Isaacg
Algo estranho: executei o código acima até a iteração # 34000, após remover a interrupção e alterar os testes um pouco, e ele encontra apenas a execução de 6. Isso é um problema com o código (duvido) ou é apenas uma propriedade ímpar da sequência?
Isaacg
@isaacg Observe que verificamos apenas as quebras de cada sequência e, portanto, perdemos todas as seqüências de cópia C ^ 6. Nos intervalos, esses parecem ser muito raros - portanto, acho que não veremos um C ^ 7 em breve.
287 Howard
Eu sei, mas como uma foi encontrada em uma quebra de sequência após apenas 2946 iterações, eu esperaria ver uma segunda em 40000 iterações, que é onde estou agora.
Isaacg
@isaacg Você pode usar o código (muito mais rápido) aqui: ideone.com/HoEKOB . Mesmo com isso, não consegui encontrar outro C ^ 6 em um ponto de sequência (ainda menos um C ^ 7).
287 Howard
5

(Não é uma resposta, mas muito tempo para um comentário.)

A seguir, uma tradução em Python do programa Ruby do @ Howard (acelerada por um fator próximo a 3 por ter apenas um getcno loop de pesquisa). No meu sistema, este encontra o primeiro C ^ 6 em 3 segundos. Em 93 horas, ele não encontra C ^ 7 em 231.000 iterações; portanto, o primeiro C ^ 7 (se existir) deve ocorrer após as 10 ^ 40677 posições mais à esquerda na cadeia 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
fonte
Com o PyPy, ele encontra C ^ 6 em menos de um segundo na minha máquina.
Dennis