termes
Un ver est une liste d'entiers non négatifs, et son élément le plus à droite (c'est-à-dire le dernier ) est appelé la tête . Si la tête n'est pas égale à 0, le ver a un segment actif constitué du bloc d'éléments contigu le plus long qui comprend la tête et a tous ses éléments au moins aussi grands que la tête . Le segment actif réduit est le segment actif avec la tête décrémentée de 1. Par exemple, le ver 3 1 2 3 2
a un segment actif 2 3 2
et le segment actif réduit l'est 2 3 1
.
Règles d'évolution
Un ver évolue pas à pas comme suit:
A l'étape t (= 1, 2, 3, ...),
si la tête est 0: supprimez la tête
sinon: remplacez le segment actif par t + 1 copies concaténées du segment actif réduit.
Réalité : tout ver finit par évoluer vers la liste vide , et le nombre d'étapes pour le faire est la durée de vie du ver .
(Voir les détails se trouvent dans le ver Principe ., Un papier par LD Beklemishev L'utilisation de « liste » pour signifier une séquence finie, et « tête » pour signifier son dernier élément, est tiré de ce papier - il ne faut pas confondre avec l'utilisation courante des listes comme type de données abstrait , où head signifie généralement le premier élément.)
Exemples (segment actif entre parenthèses)
Ver: 0,1
step worm
0(1)
1 0 0 0
2 0 0
3 0
4 <- lifetime = 4
Ver: 1,0
step worm
1 0
1 (1)
2 0 0 0
3 0 0
4 0
5 <- lifetime = 5
Ver: 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
Ver: 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
Ver: 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 = ??
Ver: 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 = ??
De côté
Les durées de vie des vers sont généralement énormes, comme le montrent les limites inférieures suivantes en termes de hiérarchie standard à croissance rapide des fonctions 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)
Remarquablement, le ver [3] a déjà une durée de vie qui dépasse de loin le nombre 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
Écrivez le sous-programme de fonction le plus court possible avec le comportement suivant:
Entrée : tout ver.
Sortie : la durée de vie du ver.La taille du code est mesurée en octets.
Voici un exemple (Python, golfs à environ 167 octets):
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 : Si t (n) est la durée de vie du ver [n], alors le taux de croissance de t (n) est à peu près celui de la fonction de Goodstein . Donc, si cela peut être joué à moins de 100 octets, cela pourrait bien donner une réponse gagnante à la question imprimable du plus grand nombre . (Pour cette réponse, le taux de croissance pourrait être considérablement accéléré en démarrant toujours le compteur de pas à n - la même valeur que le ver [n] - au lieu de le démarrer à 0.)
w[0]
élément qui est * le plus à gauche de cette liste?2 1
peut - être trop demander dans un délai raisonnable, mais un test utile est que la séquence doit commencer(2 1)
,2 0 2 0
,2 0 (2)
,2 0 (1 1 1 1)
, ...Réponses:
GolfScript (
5654 caractères)Démo en ligne
Je pense que l'astuce clé ici est probablement de maintenir le ver dans l'ordre inverse. Cela signifie qu'il est assez compact de trouver la longueur du segment actif:
.0+.({<}+??
(où le0
est ajouté comme garde pour s'assurer que nous trouvons un élément plus petit que la tête).En passant, une analyse de la durée de vie du ver. Je vais désigner le ver comme
age, head tail
(c'est-à-dire dans l'ordre inverse de la notation de la question) en utilisant des exposants pour indiquer la répétition dans la tête et la queue: par exemple2^3
est2 2 2
.Lemme : pour tout segment actif
xs
, il existe une fonctionf_xs
qui seage, xs 0 tail
transforme enf_xs(age), tail
.Preuve: aucun segment actif ne peut jamais contenir un
0
, donc l'âge au moment où nous supprimons tout avant que la queue ne soit indépendante de la queue et ne soit donc qu'une fonction dexs
.Lemme : pour tout segment actif
xs
, le verage, xs
meurt à l'âgef_xs(age) - 1
.Preuve: par le lemme précédent, se
age, xs 0
transforme enf_xs(age), []
. La dernière étape est la suppression de ce0
qui n'a pas été touché précédemment car il ne peut jamais faire partie d'un segment actif.Avec ces deux lemmes, nous pouvons étudier quelques segments actifs simples.
Pour
n > 0
,donc
f_{1^n} = x -> f_{1^{n-1}}^{x+1}(x+2)
(avec le cas de basef_{[]} = x -> x+1
, ou si vous préférezf_{1} = x -> 2x+3
). On voit quef_{1^n}(x) ~ A(n+1, x)
là oùA
est la fonction Ackermann-Péter.Cela suffit pour comprendre
1 2
(2 1
dans la notation de la question):Donc, étant donné l'entrée,
2 1
nous attendons la sortie ~A(A(5,4), A(5,4))
.et je peux vraiment commencer à comprendre pourquoi cette fonction se développe si follement.
la source
9{-1%0\{\)\.0={.0+.({<}+??\((\+.@<2$*\+}{(;}if.}do;}:L~
calcule la durée de vie du ver [9], qui dépasse de loin le nombre de Graham - et peut être golfé plus loin.GolfScript,
6962 caractèresLa fonction
C
attend le ver sur la pile et le remplace par le résultat.Exemples:
la source
*
et^
ne sont pas utilisés comme opérateurs arithmétiques de multiplier et exponentiate. Certainement, si vous voulez y soumettre votre propre réponse (sans doute supérieure), je me ferai un plaisir de supprimer la mienne.Ruby - 131 caractères
Je sais que cela ne peut pas rivaliser avec les solutions GolfScript ci-dessus et je suis assez sûr que cela peut être réduit d'un score ou de plusieurs caractères, mais honnêtement, je suis heureux d'avoir pu résoudre le problème sans golf. Grand puzzle!
Ma solution pré-golfée à partir de laquelle ce qui précède est dérivé:
la source
if foo==0
peuvent être ajustésif foo<1
. Cela peut vous faire économiser un caractère ici.reverse
.else
clause à une seule ligne, puis échanger leif..else..end
pour une déclaration ternaire. Je pourrais aussi utiliser un lambda pour enregistrer quelques caractères, je pense.Sclipting (43 caractères)
Cela attend l'entrée en tant que liste séparée par des espaces. Cela génère la bonne réponse pour
1 1
et2
, mais pour2 1
ou3
cela prend trop de temps, j'ai donc abandonné l'attente de la fin.Avec commentaire:
la source
k (83)
worm:{-1+*({x,,(,/((x+:i)#,@[y@&w;(i:~~#y)#0;-1+]),y@&~w:&\~y<*y;1_y)@~*y}.)/(1;|,/x)}
cela peut probablement être approfondi, car il implémente simplement la récurrence assez simplement.
la fonction d'évolution de base
{x,,(,/((x+:i)#,@[y@&w;(i:~~#y)#0;-1+]),y@&~w:&\~y<*y;1_y)@~*y}
, est de 65 caractères, et utilise quelques astuces pour arrêter l'augmentation de l'âge à la mort du ver. l'encapsuleur contraint une entrée d'un seul entier à une liste, inverse l'entrée (il est plus court d'écrire la récurrence en termes de ver inversé de votre notation), demande le point fixe, sélectionne l'âge comme sortie et ajuste le résultat pour tenir compte du dépassement de la dernière génération.si je fais la coercition et l'inversion manuellement, cela tombe à 80 (
{-1+*({x,,(,/((x+:i)#,@[y@&w;(i:~~#y)#0;-1+]),y@&~w:&\~y<*y;1_y)@~*y}.)/(1;x)}
).quelques exemples:
malheureusement, il n'est probablement pas très utile pour le plus grand nombre imprimable , sauf dans un sens très théorique, car il est assez lent, limité à des entiers 64 bits, et probablement pas particulièrement efficace en mémoire.
en particulier,
worm 2 1
etworm 3
juste baratiner (et jetterait probablement'wsfull
(de mémoire) si je les laissais continuer).la source
` to switch from
q` tok
et collez mon code dedans . Alternativement, vous pouvez enregistrer mon code dans un fichier avec une.k
extension et le charger dans l'interpréteur.APL (Dyalog Unicode) , 52 octets SBCS
7 octets enregistrés grâce à @ngn et @ Adám.
Essayez-le en ligne!
Explication:
la source
Scala, 198
Usage:
la source
K, 95
.
la source
C (gcc) , 396 octets
Essayez-le en ligne!
Je sais que je suis EXTRÊMEMENT en retard à la fête, mais j'ai pensé que je tenterais ma chance en C, ce qui nécessitait une implémentation de liste chaînée. Ce n'est pas vraiment du golf en plus de changer tous les identifiants en caractères uniques, mais ça fonctionne!
Dans l'ensemble, je suis assez content étant donné qu'il s'agit du 3e programme C / C ++ que j'ai jamais écrit.
la source
Haskell , 84 octets
Essayez-le en ligne!
Merci à @xnor pour deux octets.
Je pense qu'il devrait y avoir un bon moyen de prendre en compte l'incrément commun, mais je n'en ai pas encore trouvé un court.
la source
n
rétrogradez de 1.(n+1)!
deux fois, mais ma tentative n'a fait que des égales.Perl 5
-pa
, 92 octetsEssayez-le en ligne!
la source
Stax , 31 octets
Exécuter et déboguer
la source