Quine à croissance lente

30

Faites une quine.

Semble facile non? Eh bien, cette quine doit sortir elle-même plus son premier caractère, qui sort alors elle-même plus son deuxième caractère, et ainsi de suite.

De cette façon, le quine devrait en plusieurs générations produire deux copies.

Exemple: laisse votre code être x. L'exécuter devrait sortir x + x[:1]. L'exécution du programme résultant devrait produire x + x[:2]et ainsi de suite ...

Si votre code l'était foobar, son exécution devrait sortir foobarf. L'exécution devrait produire foobarfo. Et ainsi de suite et ainsi de suite suivant ce modèle:

foobar
foobarf
foobarfo
foobarfoo
foobarfoob
foobarfooba
foobarfoobar
foobarfoobarf

Votre programme doit être plus long que 2 octets et ne doit produire qu'un seul caractère supplémentaire de son propre code à chaque itération.

IQuick 143
la source
3
Je soupçonne que ce défi est impossible dans la plupart des langues, étant donné que la lecture du code source est interdite par défaut.
Ørjan Johansen
12
@ ØrjanJohansen puis Dennis se montre
Rod
2
@Rod Eh bien, je n'ai pas tout dit , c'est juste que la plupart / la plupart des langues n'ont aucun moyen évident d'ajouter des fragments de code arbitraires à la fin de telle manière que (1) cela ne donne pas une erreur de syntaxe (2) le programme peut détecter le changement.
Ørjan Johansen
3
Puisqu'il s'agit d'un quine très inhabituel, les failles habituelles du quine sont-elles toujours interdites?
Draconis

Réponses:

15

Zsh ,110 108 100 octets

a=`<&0`<<''<<<t;b=${a:0:50};printf $b$b${a:0:-50}
a=`<&0`<<''<<<t;b=${a:0:50};printf $b$b${a:0:-50}

Essayez-le en ligne!

C'est donc possible.

Explication

a=`<&0`<<''<<<t;       # Set A to everything following this line, until eof or
                       #   an empty line (which never happens before eof) encountered.
                       # A "t" is appended to prevent automatic trimming of newlines.
b=${a:0:50};           # Set B to the first line.
printf $b$b${a:0:-50}  # Print two copies of B and
                       #   A with 50 trailing characters removed.
jimmy23013
la source
11

R, 289 octets

s<-c("s<-", "i=get0('i',ifnotfound=0)+1;p=paste0(s,substr(get0('p',ifnotfound=s),1,i),collapse='');cat(s[1]);dput(s);cat(paste0(s[2],substr(p,1,i)))#")
i=get0('i',ifnotfound=0)+1;p=paste0(s,substr(get0('p',ifnotfound=s),1,i),collapse='');cat(s[1]);dput(s);cat(paste0(s[2],substr(p,1,i)))#

crédit à cette quine d'inspiration. Fonctionne uniquement s'il est exécuté dans le même environnement R que le quine précédent.

Giuseppe
la source
une explication sera à venir ... Je ne l'ai pas encore testé 288 fois, mais je suis assez convaincu que c'est correct
Giuseppe
Cela devrait être de 289 octets, car le quine ajoute un caractère de nouvelle ligne, mais de toute façon, c'est génial que vous l'ayez résolu!
IQuick 143
ah, vous avez raison, stupide en catajoutant des nouvelles lignes.
Giuseppe
Mais est-ce un programme complet? Les codes générés sont-ils des programmes complets?
jimmy23013
@ jimmy23013 Pour autant que je sache, cette réponse et le code généré sont des programmes complets. Il n'y a pas mainou aucune autre structure obligatoire comme celle de R. En outre, la question ne demande pas explicitement un programme complet, donc une fonction ou similaire ferait l'affaire.
Steadybox
5

Alice , 29 octets

4P.a+80pa2*&wdt,kd&w74*,.ok@

Essayez-le en ligne!

Le caractère non imprimable est 0x18.

Explication

Le problème avec les "quines Fungeoid habituelles est que si nous répétons tout le code source, nous obtenons également des informations supplémentaires "et la chaîne ne couvre plus l'intégralité du code source. Je suppose que c'est pourquoi la réponse existante utilise à la gplace l'approche de triche .

Cette réponse utilise l' "approche basée sur, mais au lieu d'inclure un "dans la source, nous l'écrivons dans le programme au moment de l'exécution. De cette façon, il n'y en aura jamais qu'une, "quelle que soit la fréquence de répétition du programme (car nous ne l'écrivons que sur une coordonnée spécifique, indépendamment de la taille du programme).

L'idée générale est alors que nous créons une représentation de tout le code source sur la pile, mais ne parcourons que les 29 premiers caractères (c'est-à-dire la longueur du programme) avec la longueur de la boucle déterminée par la taille du code. Par conséquent, nous pouvons ajouter des caractères arbitraires (sauf les sauts de ligne) après @et le résultat sera toujours une répétition cyclique du programme principal, un caractère de plus que la source.

4P   Push 4! = 24. This is the code point of the unprintable, which we're 
     using as a placeholder for the quote.
.a+  Duplicate it and add 10, to get 34 = '"'.
80p  Write '"' to cell (8,0), i.e. where the first unprintable is.
    Placeholder, becomes " by the time we get here, and pushes the code
     points of the entire program to the stack. However, since we're already
     a good bit into the program, the order will be messed up: the bottom
     of the stack starts at the 24 (the unprintable) followed by all 
     characters after it (including those from extraneous repetitions). Then 
     on top we have the characters that come in front of the `"`. 
     So if the initial program has structure AB, then any valid program has
     the form ABC (where C is a cyclic repetition of the initial program),
     and the stack ends up holding BCA. We don't care about C, except to
     determine how big the program is. So the first thing we need to do is
     bring B to the top, so that we've got the initial program on top of
     the stack:
a2*  Push 10*2 = 20.
&w   Run the following section 21 times, which is the length of B.

  dt,  Pull up the value at the bottom of the stack.

k    End of loop.
d&w  Run the following section D+1 times, where D is the length of ABC.

  74*  Push 28, one less than the number of characters in AB.
  ,    Pull up the 29th stack element, which is the next character to print.
  .o   Print a copy of that character.

k    End of loop.
@    Terminate the program.
Martin Ender
la source
Excellente solution. J'aime l'explication.
IQuick 143
4

Perl 5 , 83 octets (y compris la nouvelle ligne finale)

$_=q($/=$;;$_="\$_=q($_);eval
__END__
".<DATA>;print$_,/(.).{82}\z/s);eval
__END__

Essayez-le en ligne!

Le bon vieux __DATA__jeton permet d'ajouter facilement une chaîne arbitraire à n'importe quel programme Perl, auquel le programme principal peut ensuite accéder via le <DATA>descripteur de fichier (et en fait l'utiliser __END__, ce qui fait la même chose pour la compatibilité descendante, au lieu d' __DATA__enregistrer deux octets supplémentaires) .

Notez que ce programme ne lit pas son propre code source, mais uniquement les données d'entrée supplémentaires ajoutées à sa source après le __END__jeton. En effet, le __END__jeton et tout ce qui se trouve après fonctionne un peu comme un littéral de chaîne terminé à la fin de l'entrée.

Notez également que, pour répondre exactement aux spécifications, ce programme doit se terminer par une nouvelle ligne. Si ce n'est pas le cas, la nouvelle ligne est en fait automatiquement ajoutée après la seconde __END__, mais la première sortie d'itération ne sera plus précisément égale au code plus son premier octet.

Ilmari Karonen
la source
2

Befunge-98 , 30 octets

0>:#;0g:840#;+*#1-#,_$a3*%0g,@

Essayez-le en ligne!

J'essaie d'utiliser Befunge-98 qui utilise une quine terminée par un espace qui compte également le nombre de caractères sortis. Utilise cependant la gcommande.

IQuick 143
la source
Vous voudrez peut-être mentionner dans la première ligne qu'il ne s'agit pas de concurrence / triche, juste pour décourager les votes négatifs qu'il pourrait autrement recevoir.
quintopie
2

PHP, 146 octets

ob_start(function($s){return($u=substr($s,0,73)).$u.substr($s,0,-72);})?>ob_start(function($s){return($u=substr($s,0,73)).$u.substr($s,0,-72);})?>

Il doit être exécuté à l'aide -rde la ligne de commande.

jimmy23013
la source
Ne semble pas fonctionner quand je l' essaye en ligne! , c'est juste une quine ordinaire.
Ørjan Johansen
@ ØrjanJohansen Vous devriez l'exécuter avec php -r 'command'.
jimmy23013
Gah, je ne peux pas le faire fonctionner. TIO semble ignorer les arguments -r.
Ørjan Johansen
@ ØrjanJohansen Voici comment vous devriez le tester.
jimmy23013
Aha. Je dois avoir mal compris quelque chose à l'époque. Maintenant, j'ai réussi à le faire fonctionner avec PHP comme paramètre de langue aussi.
Ørjan Johansen
2

Enchantements runiques , 61 octets

803X4+kw.'.q}͍}͍}͍}͍}͍}͍}͍}͍}͍::l͍5X-:}-$:l͍{-1--@

Essayez-le en ligne!

Utilise une approche similaire à la réponse d'Alice: écrit de manière réfléchie la "commande de chaîne dans le code afin qu'il n'y en ait qu'un. Il reste beaucoup de manipulation de chaînes et de piles pour récupérer le programme d'origine, combien d'octets supplémentaires sont nécessaires et imprimer les morceaux nécessaires.

La séquence fait pivoter la représentation de la chaîne en mémoire autour de sorte que le 803X4+kws'affiche au début plutôt qu'à la fin, en raison de la position du "et il n'y a pas de moyen plus facile de gérer cette opération sans avoir à calculer beaucoup de nombres maladroits .

Alors que le programme d'origine est de 61 octets, sa longueur de chaîne n'est que de 50, ce qui est facile à construire car 5Xce n'est qu'une coïncidence que cela n'a pas besoin d'être complété après avoir contenu toutes les fonctionnalités nécessaires (par exemple, un programme de longueur 49 serait plus facile pour coder comme 50avec un octet de remplissage que pour coder un littéral 49, tandis que 51serait codé comme 5X3+ou 53, devant tenir compte de ses propres octets supplémentaires).

Draco18s
la source