Termos e Condições
Um worm é qualquer lista de números inteiros não negativos e seu elemento mais à direita (ou seja, o último ) é chamado de cabeça . Se a cabeça não for 0, o worm tem um segmento ativo que consiste no bloco contíguo mais longo de elementos que inclui a cabeça e tem todos os seus elementos pelo menos tão grandes quanto a cabeça . O segmento ativo reduzido é o segmento ativo com a cabeça decrementada em 1. Por exemplo, o worm 3 1 2 3 2
possui segmento ativo 2 3 2
e o segmento ativo reduzido é 2 3 1
.
Regras da evolução
Um worm evolui passo a passo da seguinte maneira:
Na etapa t (= 1, 2, 3, ...),
se o cabeçalho for 0: exclua o cabeçalho
mais: substitua o segmento ativo por t + 1 cópias concatenadas do segmento ativo reduzido.
Fato : Qualquer worm acaba evoluindo para a lista vazia , e o número de etapas para isso é a vida útil do worm .
(Detalhes podem ser encontrados em The Worm Principle , um artigo de LD Beklemishev. O uso de "list" para significar uma sequência finita e "head" para significar seu último elemento, são retirados deste artigo - ele não deve ser confundido com o uso comum de listas como um tipo de dados abstrato , onde head geralmente significa o primeiro elemento.)
Exemplos (segmento ativo entre parênteses)
Verme: 0,1
step worm
0(1)
1 0 0 0
2 0 0
3 0
4 <- lifetime = 4
Verme: 1,0
step worm
1 0
1 (1)
2 0 0 0
3 0 0
4 0
5 <- lifetime = 5
Verme: 1,1
step worm
(1 1)
1 1 0 1 0
2 1 0(1)
3 1 0 0 0 0 0
4 1 0 0 0 0
5 1 0 0 0
...
8 (1)
9 0 0 0 0 0 0 0 0 0 0
10 0 0 0 0 0 0 0 0 0
...
18 0
19 <- lifetime = 19
Verme: 2
step worm
(2)
1 (1 1)
2 1 0 1 0 1 0
3 1 0 1 0(1)
4 1 0 1 0 0 0 0 0 0
5 1 0 1 0 0 0 0 0
6 1 0 1 0 0 0 0
...
10 1 0(1)
11 1 0 0 0 0 0 0 0 0 0 0 0 0 0
12 1 0 0 0 0 0 0 0 0 0 0 0 0
...
24 (1)
25 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
...
50 0
51 <- lifetime = 51
Verme: 2,1
(2 1)
1 2 0 2 0
2 2 0(2)
3 2 0(1 1 1 1)
4 2 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0
5 2 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0(1 1 1)
6 2 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0
7 2 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0(1 1)
8 2 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0{1 0}^9
...
?? <- lifetime = ??
Verme: 3
step worm
(3)
1 (2 2)
2 (2 1 2 1 2 1)
3 2 1 2 1 2 0 2 1 2 1 2 0 2 1 2 1 2 0 2 1 2 1 2 0
4 2 1 2 1 2 0 2 1 2 1 2 0 2 1 2 1 2 0 2 1 2 1(2)
5 2 1 2 1 2 0 2 1 2 1 2 0 2 1 2 1 2 0(2 1 2 1 1 1 1 1 1 1)
6 2 1 2 1 2 0 2 1 2 1 2 0 2 1 2 1 2 0{2 1 2 1 1 1 1 1 1 0}^7
7 2 1 2 1 2 0 2 1 2 1 2 0 2 1 2 1 2 0{2 1 2 1 1 1 1 1 1 0}^6 (2 1 2 1 1 1 1 1 1)
... ...
?? <- lifetime = ??
a parte, de lado
A vida útil do worm é tipicamente enorme, como mostra os seguintes limites inferiores em termos da hierarquia padrão de funções de crescimento rápido f α :
worm lower bound on lifetime
---------------- ------------------------------------------
11..10 (k 1s) f_k(2)
2 f_ω(2)
211..1 (k 1s) f_(ω+k)(2)
2121..212 (k 2s) f_(ωk)(2)
22..2 (k 2s) f_(ω^k)(2)
3 f_(ω^ω)(2)
...
n f_(ω^ω^..^ω)(2) (n-1 ωs) > f_(ε_0) (n-1)
Notavelmente, o worm [3] já tem uma vida útil que ultrapassa em muito o número de Graham , G:
f ω ω (2) = f ω 2 (2) = f ω2 (2) = f ω + 2 (2) = f ω + 1 (f ω + 1 (2)) >> f ω + 1 (64) > G.
Code Golf Challenge
Escreva o subprograma de função mais curto possível com o seguinte comportamento:
Entrada : Qualquer verme.
Saída : a vida útil do worm.O tamanho do código é medido em bytes.
Aqui está um exemplo (Python, golfs to 167 bytes):
from itertools import *
def T(w):
w=w[::-1]
t=0
while w:
t+=1
if w[0]:a=list(takewhile(lambda e:e>=w[0],w));a[0]-=1;w=a*(t+1)+w[len(a):]
else:w=w[1:]
return t
NB : Se t (n) é a vida útil do worm [n], a taxa de crescimento de t (n) é aproximadamente a da função Goodstein . Então, se isso pode ser golfed abaixo de 100 bytes, ele poderia muito bem dar uma resposta vencedora para o maior número Printable questão . (Para essa resposta, a taxa de crescimento pode ser muito acelerada sempre iniciando o contador de passos em n - o mesmo valor que o worm [n] - em vez de iniciá-lo em 0.)
w[0]
* que é o elemento mais à esquerda dessa lista?2 1
poderia ser pedir muito em um tempo razoável, mas um teste útil é que a seqüência deve começar(2 1)
,2 0 2 0
,2 0 (2)
,2 0 (1 1 1 1)
, ...Respostas:
GolfScript (
5654 caracteres)Demonstração online
Eu acho que o principal truque aqui é provavelmente manter o worm em ordem inversa. Isso significa que é bastante compacto encontrar o comprimento do segmento ativo:
.0+.({<}+??
(onde o0
é adicionado como uma proteção para garantir que encontramos um elemento menor que a cabeça).Como um aparte, algumas análises da vida útil do verme. Denotarei o worm como
age, head tail
(ou seja, na ordem inversa da anotação da pergunta) usando expoentes para indicar repetição na cabeça e na cauda: por exemplo,2^3
é2 2 2
.Lema : para qualquer segmento ativo
xs
, existe uma funçãof_xs
que seage, xs 0 tail
transforma emf_xs(age), tail
.Prova: nenhum segmento ativo pode conter a
0
, portanto, a idade em que excluímos tudo antes da cauda é independente da cauda e, portanto, é apenas uma função dexs
.Lema : para qualquer segmento ativo
xs
, o vermeage, xs
morre com a idadef_xs(age) - 1
.Prova: pelo lema anterior, se
age, xs 0
transforma emf_xs(age), []
. A etapa final é a exclusão daquilo0
que não é tocado anteriormente porque nunca pode fazer parte de um segmento ativo.Com esses dois lema, podemos estudar alguns segmentos ativos simples.
Para
n > 0
,então
f_{1^n} = x -> f_{1^{n-1}}^{x+1}(x+2)
(com base casof_{[]} = x -> x+1
, ou se você preferirf_{1} = x -> 2x+3
). Vemos quef_{1^n}(x) ~ A(n+1, x)
ondeA
está a função Ackermann – Péter.Isso é suficiente para entender
1 2
(2 1
na notação da pergunta):Então, dada a entrada
2 1
, esperamos uma saída ~A(A(5,4), A(5,4))
.e posso realmente começar a entender por que essa função cresce tão insanamente.
fonte
9{-1%0\{\)\.0={.0+.({<}+??\((\+.@<2$*\+}{(;}if.}do;}:L~
calcula a vida útil do worm [9], que excede em muito o número de Graham - e pode ser golfe ainda mais.GolfScript,
6962 caracteresA função
C
espera o worm na pilha e o substitui pelo resultado.Exemplos:
fonte
*
e^
não esteja sendo usado como operador aritmético da multiplicação e exponencial. Certamente, se você quiser enviar sua própria resposta (sem dúvida superior) lá, eu removerei a minha com prazer.Ruby - 131 caracteres
Sei que isso não pode competir com as soluções GolfScript acima e tenho quase certeza de que isso pode reduzir uma pontuação ou mais caracteres, mas, sinceramente, estou feliz por ter conseguido resolver o problema sem esforço. Ótimo quebra-cabeça!
Minha solução pré-golfe da qual deriva o acima:
fonte
if foo==0
pode ser aparadoif foo<1
. Isso pode economizar um caractere aqui.reverse
.else
reduzir a cláusula a uma linha e depois trocar aif..else..end
declaração por uma declaração ternária. Eu também poderia usar um lambda para salvar alguns caracteres, eu acho.Sclipting (43 caracteres)
Isso espera a entrada como uma lista separada por espaço. Isso gera a resposta correta para
1 1
e2
, mas por2 1
ou3
leva muito tempo, então desisti de esperar que ela terminasse.Com comentários:
fonte
k (83)
worm:{-1+*({x,,(,/((x+:i)#,@[y@&w;(i:~~#y)#0;-1+]),y@&~w:&\~y<*y;1_y)@~*y}.)/(1;|,/x)}
isso provavelmente pode ser ainda mais jogado, pois apenas implementa a recorrência de maneira bastante direta.
a função básica de evolução
{x,,(,/((x+:i)#,@[y@&w;(i:~~#y)#0;-1+]),y@&~w:&\~y<*y;1_y)@~*y}
, é de 65 caracteres e usa alguns truques para parar de aumentar a idade em que o verme morre. o invólucro coage uma entrada de um único número inteiro para uma lista, reverte a entrada (é mais curto escrever a recorrência em termos de um worm revertido da sua notação), solicita o ponto de correção, seleciona a idade como a saída e ajusta o resultado para explicar a superação na última geração.se eu fizer a coerção e a reversão manualmente, ele cai para 80 (
{-1+*({x,,(,/((x+:i)#,@[y@&w;(i:~~#y)#0;-1+]),y@&~w:&\~y<*y;1_y)@~*y}.)/(1;x)}
).alguns exemplos:
infelizmente, provavelmente não é de muita utilidade para o Maior Número Imprimível , exceto em um sentido muito teórico, pois é bastante lento, limitado a números inteiros de 64 bits e, provavelmente, não é particularmente eficiente em termos de memória.
em particular,
worm 2 1
eworm 3
apenas agite (e provavelmente jogaria'wsfull
(sem memória) se eu os deixasse continuar).fonte
` to switch from
q` tok
e cole meu código. Como alternativa, você pode salvar meu código em um arquivo com uma.k
extensão e carregá-lo no intérprete.APL (Dyalog Unicode) , 52 bytes SBCS
Economizou 7 bytes graças a @ngn e @ Adám.
Experimente online!
Explicação:
fonte
Scala, 198
Uso:
fonte
K, 95
.
fonte
C (gcc) , 396 bytes
Experimente online!
Sei que estou extremamente atrasado para a festa, mas pensei em tentar isso em C, o que exigia uma implementação de lista vinculada. Não é realmente um jogo de golfe, além de alterar todos os identificadores para caracteres únicos, mas funciona!
No geral, estou muito feliz considerando que este é o terceiro programa C / C ++ que eu já escrevi.
fonte
Haskell , 84 bytes
Experimente online!
Obrigado a @xnor por dois bytes.
Sinto que deve haver uma boa maneira de fatorar o incremento comum, mas ainda não encontrei um pequeno.
fonte
n
reduza para 1.(n+1)!
duas vezes, mas minha tentativa só empatou.Perl 5
-pa
, 92 bytesExperimente online!
fonte
Stax , 31 bytes
Execute e depure
fonte