APL (158 caractères, score = 4)
'''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0
J'utilise Dyalog APL ici. Le nombre de cycles peut être augmenté de un en ajoutant 0
(0 suivi d'un espace) à la fin de l'expression et à la fin de la chaîne (avant '''
). La durée du cycle est (# 0's) + 1
et la longueur de l'expression est 150 + 4*(cycle length))
. En supposant que nous continuons d'ajouter des zéros pour toujours, le score est Limit[(150 + 4*n)/(n - 1), n -> Infinity] = 4
, où n
est la durée du cycle.
Voici un exemple avec une longueur de cycle = 6:
'''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0
0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0
0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0
0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0
0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0
0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0
0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0
0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0
0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0
0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1
0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1
'''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0
192 caractères, score = 2
'''{2≠⍴⍺:¯3⌽(2×1+⍴⍺)⍴(1+⍴⍺)⍴⍺ ⋄ a←⊃2⌷⍺ ⋄ ⍵=0:¯2⌽(2×1+⍴a)⍴(1+⍴a)⍴a⋄(-4+⌊10⍟⊃⍺)⌽(2×1+⍴a)⍴(1+⍴a)⍴a}01'''{2≠⍴⍺:¯3⌽(2×1+⍴⍺)⍴(1+⍴⍺)⍴⍺⋄a←⊃2⌷⍺⋄⍵=0:¯2⌽(2×1+⍴a)⍴(1+⍴a)⍴a⋄(-4+⌊10⍟⊃⍺)⌽(2×1+⍴a)⍴(1+⍴a)⍴a}01
Selon l'implémentation, un point d'échec pourrait être lorsque l'entier préfixé à la chaîne est trop grand. Théoriquement, cependant, nous pouvons ajouter un cycle en ajoutant deux caractères - un 1
à la fin de la chaîne (avant '''
) et un 1
à la fin de la ligne entière.
200 caractères, score = 1
'''{a←{2=⍴⍵:⊃2⌷⍵⋄⍵}⍺⋄(⍺{⍵=9:⍬⋄⍕1+{2=⍴⍵:10×⊃⍵⋄0}⍺}⍵),(¯2⌽(2×1+⍴a)⍴(1+⍴a)⍴a),⍺{⍵=9:(⍕9),⍕⊃⍺⋄⍕⌊⍵÷10}⍵}'''{a←{2=⍴⍵:⊃2⌷⍵⋄⍵}⍺⋄(⍺{⍵=9:⍬⋄⍕1+{2=⍴⍵:10×⊃⍵⋄0}⍺}⍵),(¯2⌽(2×1+⍴a)⍴(1+⍴a)⍴a),⍺{⍵=9:(⍕9),⍕⊃⍺⋄⍕⌊⍵÷10}⍵}91
Mon implémentation APL n'a pas d'entiers de précision illimitée par défaut, donc l'entier est converti en un flottant quand il devient trop grand, ce qui rend la sortie incorrecte. Donc celui-ci est le plus capricieux, mais théoriquement (soit à la main ou avec un interpréteur APL différent), il devrait avoir un score de 1. Ajoutez simplement un 1
à la fin de l'expression, et vous obtenez un autre cycle.
Aperçu (avec un quine plus court)
Je vais donner un aperçu de la première version, car je pense que c'est probablement la plus facile à comprendre. Avant d'aborder cette version, cependant, nous allons considérer un quine simple dans APL :
1⌽22⍴11⍴'''1⌽22⍴11⍴'''
J'ai trouvé que l'une des meilleures façons de comprendre certaines expressions APL est de regarder la sortie tout au long de la cascade d'opérateurs / fonctions. Tous les opérateurs et fonctions dans APL sont associatifs à droite et ont la même priorité, voici donc, de droite à gauche:
'''1⌽22⍴11⍴'''
: Ceci est juste un littéral de chaîne (une liste de caractères). ''
est le moyen APL d’échapper aux guillemets simples. Sortie: '1⌽22⍴11⍴'
.
11⍴'''1⌽22⍴11⍴'''
: Ici, nous remodelons ( ⍴
) la chaîne pour qu'elle soit de longueur 11
. Parce que la longueur de la chaîne est inférieure à 11, elle est répétée (c'est-à-dire 5⍴'abc'
qu'elle donnerait 'abcab'
). Sortie: '1⌽22⍴11⍴''
. Nous avons donc maintenant deux guillemets à la fin - nous arrivons quelque part!
22⍴11⍴'''1⌽22⍴11⍴'''
: De même, nous remodelons maintenant notre sortie précédente pour qu'elle soit de longueur 22
. Sortie: '1⌽22⍴11⍴'''1⌽22⍴11⍴''
. Nous y sommes presque - nous avons juste besoin de déplacer la première citation unique à la fin.
1⌽22⍴11⍴'''1⌽22⍴11⍴'''
: Ici, nous faisons pivoter ( ⌽
) la liste des caractères de 1
. Cela déplace le premier caractère de la chaîne à la fin. Comme autre exemple, 2⌽'abcdef'
retourne 'cdefab'
. Sortie: 1⌽22⍴11⍴'''1⌽22⍴11⍴'''
.
Le quine tournant
Ce court quine est la base principale de notre quine rotatif. Maintenant, avec cela à l'esprit, jetons un œil à notre quine:
'''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0
{ ... }
définit une fonction sans nom, c'est là que nous ferons le travail. Notez que les fonctions dans APL prennent un argument droit, noté par ⍵
, et un argument gauche facultatif, noté ⍺
(pensez infixe). Nous voulons alimenter cette fonction à la fois notre chaîne de quine et quelque chose pour nous aider à créer un nombre arbitraire de cycles. Pour nous faciliter la tâche (et pour quiconque souhaite ajouter des cycles), nous faisons de la chaîne quine l'argument de gauche. Le bon argument est donc l'endroit où nous mettons notre liste de cycles. 2 éléments ou plus séparés par un espace créent une liste, donc dans cet exemple, nous avons une liste à 2 éléments composée de a 1
et a 0
.
Nous pouvons voir que la fonction ressemble à la quine d'avant. Nous avons le même ...⌽...⍴...⍴...
formulaire que précédemment. C'est donc bien - nous comprenons au moins cela! Nous allons plonger plus profondément dans les ellipses, en commençant par tout ce qui suit le dernier ⍴
: ⊃,/(~^/¨⍺=0)/⍺
.
- Comme vous pouvez le voir en regardant l'exemple ci-dessus, nous préfixons la chaîne avec les 0 du côté droit, en ajoutant un à chaque itération; mais nous ne nous soucions pas de ceux en ce moment. Nous voulons juste la chaîne!
- Tout d'abord, considérez ce qui est entre parenthèses. (Ils se regroupent comme dans la plupart des autres langues, soit dit en passant.)
⍺=0
renvoie une liste, dans ce cas, avec la même forme que ⍺
, où chaque élément de ⍺
est remplacé par a 1
s'il est égal à 0
, et 0
sinon. Ceci est effectué récursivement; donc si nous avons une liste d'une liste d'une liste de caractères, les caractères individuels seront testés par rapport à 0, et vous récupérerez une liste d'une liste d'une liste de valeurs binaires.
- Donc, si se
⍺
compose uniquement de notre chaîne, nous récupérons une liste de 0. Sinon, notre argument de gauche est précédé de 0 (par exemple 0 0 0 'quinestring'
), il s'agit donc d'une liste composée de 0 et d'une autre liste, notre chaîne. Ensuite, notre sortie ressemble 1 1 1 <sub-list of zeros>
.
^/¨⍺=0
: Nous appliquons la fonction dérivée ^/
, qui réduit ( /
) à l'aide de la fonction logique AND ( ^
), à chaque ¨
élément ( ) de ⍺=0
. C'est pour aplatir la sous-liste des zéros afin que nous puissions considérer la chaîne quine comme une valeur binaire. Considérant l'exemple précédent, la sortie serait 1 1 1 0
.
~
: Nous binaire PAS chacune des valeurs d'avant (par exemple, le retour 0 0 0 1
).
(~^/¨⍺=0)/⍺
: Pour chaque élément de ⍺
, nous répliquons ( /
) le nombre de fois donné par l'élément correspondant dans l'argument de gauche. Cela élimine tous les 0, ne nous laissant que notre chaîne de quine.
⊃,/
est une paperasse nécessaire pour s'assurer que nous récupérons une liste de caractères aplatie, en réduisant le résultat avec la fonction de concaténation ( ,
). Si l'entrée est déjà une liste aplatie (c'est-à-dire que l'argument de gauche de notre fonction principale n'est que la chaîne), nous obtenons une liste à 1 élément contenant cette liste. Dans l'autre cas, lorsque nous avons une liste composée d'une sous-liste pour la chaîne, nous obtenons la même chose (une liste avec une sous-liste). Nous décompressons ensuite this ( ⊃
), ne nous donnant que le premier élément de la liste (c'est-à-dire la sous-liste de caractères). Cela peut sembler inutile, mais sinon nous essaierions alors de remodeler une liste à 1 élément!
Ensuite, nous regardons la longueur donnée pour le premier remodelage, entre parenthèses:
⍺,⍵
: Nous concaténons le bon argument au premier argument
⊃,/⍺,⍵
: Comme avant - aplatissez la liste.
+/0=⊃,/⍺,⍵
: Additionnez le nombre de zéros dans la liste en réduisant ( /
) en utilisant l'addition (+
).
2×+/0=⊃,/⍺,⍵
: Multipliez ce nombre par deux.
z←2×+/0=⊃,/⍺,⍵
: Assign ( ←
) , le résultat à une variable, z
. Pour récapituler, z
c'est maintenant le double du nombre de zéros trouvés dans les arguments gauche et droit.
77+z←2×+/0=⊃,/⍺,⍵
: Nous ajoutons ensuite 77
, pour les caractères de la chaîne de quine, en ignorant tout après l'espace suivant 1
. Comme dans l'exemple de quine initial, nous ajoutons 1 à la longueur de la chaîne pour obtenir un autre guillemet simple.
- La sortie de cette refonte, dans cet exemple, est:
'{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 ''
L'argument de la refonte qui suit est simple et reflète le quine court (2 fois la longueur de la première refonte). Notre production est maintenant:
'{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 ''
Maintenant, pour la dernière étape, où nous calculons la rotation de la chaîne de sortie:
- Comme vous pouvez le voir en regardant la sortie précédente, nous voulons la faire pivoter (un montant négatif) pour ramener les 2 guillemets finaux au début. Parce que nous voulons un
0
(et un autre espace) se déplacent également au début, nous voulons le faire pivoter de 3 caractères supplémentaires.
+/+/¨⍺=0
: Additionnez le nombre de zéros dans l' argument de gauche . Le premier (à droite) +/¨
additionne le nombre de chaque élément (c'est-à-dire une sous-liste ou simplement un entier), et le second +/
nous donne la somme de cette liste résultante.
5+2×+/+/¨⍺=0
: Multipliez par deux (pour faire également pivoter les espaces) et ajoutez 5 (le résultat que nous avons trouvé auparavant).
- Maintenant, nous soustrayons la valeur précédente de l'argument de gauche à
-
pour gérer le cas lorsque nous atteignons la fin de notre cycle:
(3+z)×^/⍵
: ET tous les éléments du bon argument ensemble pour voir si nous avons atteint notre fin ( 1
), et multipliez-le par 3+z
.
Et nous avons terminé!