Maison > développement back-end > Tutoriel Python > QuineRelay : Naissance du serpent Quine

QuineRelay : Naissance du serpent Quine

王林
Libérer: 2024-08-07 22:30:12
original
1231 Les gens l'ont consulté

Dans les aventures précédentes de la série de blogs Quine, nous avons exploré comment écrire nos propres Quines et Introns. Aujourd'hui, nous verrons ce que sont les QuineRelays et comment vous pouvez exploiter les Introns pour les créer.

Imaginez un cercle de programmes, chacun écrit dans une langue différente. Chaque programme de ce cercle a un seul objectif : imprimer le code source du programme suivant dans la séquence. Le dernier programme boucle ensuite la boucle en imprimant le code source du tout premier programme.

Essentiellement, les QuineRelays sont un ensemble de n programmes, dans n langages différents tels que :

  • Chaque programme affiche la source du suivant.
  • Le dernier programme renvoie la source du premier. Pensez à la liste circulaire liée ici. Le dernier exemple est hallucinant !

Voyons quelques exemples pour mieux saisir le concept.


relais de 2ème ordre

Ce QuineRelay de 2e ordre comprend un programme JavaScript qui imprime un programme Python, qui réimprime ensuite le programme JavaScript d'origine. C'est un duo dynamique d'auto-réplication.
JavaScript → Python ⥀

JavaScript : essayez-le en ligne !

console.log((q=_=>`print(${JSON.stringify(`console.log((q=${q+[]})())`)})`)())
Copier après la connexion

Python : essayez-le en ligne !

print("console.log((q=_=>`print(${JSON.stringify(`console.log((q=${q+[]})())`)})`)())")
Copier après la connexion

relais de 3ème ordre

Les choses deviennent encore plus intéressantes avec un QuineRelay de 3ème ordre. Celui-ci commence par un programme Haskell, qui génère un programme Python, qui génère un programme Ruby, et enfin, le programme Ruby revient au programme Haskell d'origine.
Haskell → Python2 → Ruby ⥀

Haskell : Essayez-le en ligne !

q a b c=putStrLn $ b ++ [toEnum 10,'q','('] ++ show b ++ [','] ++ show c ++ [','] ++ show a ++ [')']
main=q "q a b c=putStrLn $ b ++ [toEnum 10,'q','('] ++ show b ++ [','] ++ show c ++ [','] ++ show a ++ [')']" "def q(a,b,c):print b+chr(10)+'q('+repr(b)+','+repr(c)+','+repr(a)+')'" "def e(x) return 34.chr+x+34.chr end;def q(a,b,c) print b+10.chr+'main=q '+e(b)+' '+e(c)+' '+e(a)+' '+10.chr end"
Copier après la connexion

Python2 : essayez-le en ligne !

def q(a,b,c):print b+chr(10)+'q('+repr(b)+','+repr(c)+','+repr(a)+')'
q("def q(a,b,c):print b+chr(10)+'q('+repr(b)+','+repr(c)+','+repr(a)+')'","def e(x) return 34.chr+x+34.chr end;def q(a,b,c) print b+10.chr+'main=q '+e(b)+' '+e(c)+' '+e(a)+' '+10.chr end","q a b c=putStrLn $ b ++ [toEnum 10,'q','('] ++ show b ++ [','] ++ show c ++ [','] ++ show a ++ [')']")
Copier après la connexion

Ruby : Essayez-le en ligne !

def e(x) return 34.chr+x+34.chr end;def q(a,b,c) print b+10.chr+'main=q '+e(b)+' '+e(c)+' '+e(a)+' '+10.chr end
q("def e(x) return 34.chr+x+34.chr end;def q(a,b,c) print b+10.chr+'main=q '+e(b)+' '+e(c)+' '+e(a)+' '+10.chr end","q a b c=putStrLn $ b ++ [toEnum 10,'q','('] ++ show b ++ [','] ++ show c ++ [','] ++ show a ++ [')']","def q(a,b,c):print b+chr(10)+'q('+repr(b)+','+repr(c)+','+repr(a)+')'")
Copier après la connexion

relais de 4ème ordre

Voici un QuineRelay de 4ème ordre : Ruby → Java → C# → Python ⥀
GitHub


À travers les cultures, il existe plusieurs symbolismes partagés. L’un d’eux est l’Ouroboros, qui fait référence aux mythologies égyptienne, grecque, romaine, hindoue, sibérienne, nordique, africaine et sud-américaine. L'Ouroboros est un ancien symbole représentant un serpent ou un dragon consommant sa propre queue, représentant le cycle éternel de création et de destruction.

QuineRelay: Birth of the Quine serpent

Dans la mythologie nordique, Jörmungandr est un serpent colossal, l'enfant du milieu de Loki et de la géante Angrboða. Odin jeta Jörmungandr dans l'océan entourant Midgard (le royaume des humains), où le serpent devint si immense qu'il encercla le monde et saisit sa propre queue. En raison du fait qu'il entoure Midgard (la Terre), il est appelé le Serpent du Monde - Ouroboros. Jörmungandr lâchant sa queue est l'un des signes du début du Ragnarök (la bataille finale du monde).

Les relais Quine incarnent assez bien ce symbolisme, car chaque programme du cycle donne naissance au suivant, pour finalement renaître, et sont donc surnommés Ouroboros programmes.


Relais Ouroboros d'ordre 128

Accrochez-vous à vos sièges. Voici un Ouroboros QuineRelay d'ordre 128. Oui, vous avez bien lu. 128 !!!
Ruby → Rust → Scala → ... (120 autres) ... → Python → R → Ratfor → rc → REXX ⥀
GitHub

QuineRelay: Birth of the Quine serpent

Comme si ce n'était pas assez impressionnant, il comprend un œuf de Pâques. Le code Ruby original lors d'un zoom arrière contient un dragon Ouroboros !

QuineRelay: Birth of the Quine serpent


Écrire votre propre QuineRelay

Commençons l'intron Python que nous avons écrit plus tôt et essayons de le transformer en QuineRelay de 2ème ordre.

Python Intron : essayez-le en ligne !

intron = 'wubbalubbadubdub'
data = "print('intron =', repr(intron)); print('data =', repr(data)); print(data)"
print('intron =', repr(intron)); print('data =', repr(data)); print(data)
Copier après la connexion

Grâce à la magie des introns, nous pouvons désormais facilement mettre la partie code d'un Quine frère d'une langue différente dans l'intron. Produire un programme de la forme :

Python :

intron = "code part of sibling"
data = "code part of self"
print('intron =', repr(intron)); print('data =', repr(data)); print(data)
Copier après la connexion

Depuis, chaque variable est juste, agissant comme donnée d'un Quine différent. Renommons data et intron, respectivement en d1 et d2.

Python :

d1 = "code part of self"
d2 = "code part of sibling"
print('d1 =', repr(d1)); print('d2 =', repr(d2)); print(d1)
Copier après la connexion

Maintenant, d2 agit comme un intron, mais le programme ci-dessus essayait toujours d'imprimer une partie du code de lui-même. Pour qu'il imprime la source du suivant, imprimons(d2) au lieu de print(d1) à la fin.

Python :

d1 = "code part of self"
d2 = "code part of sibling"
print('d1 =', repr(d1)); print('d2 =', repr(d2)); print(d2)
Copier après la connexion

Nous savons déjà que le contenu de d1 n'est qu'une copie de la ligne 3. Mais nous n'avons pas encore le contenu de d2.

Dites, nous voulions créer un QuineRelay avec JavaScript. Écrivons un intron similaire en JS.

JavaScript :

d1 = "code part of sibling"
d2 = "code part of self"
console.log(`d1 = ${JSON.stringify(d1)}`); console.log(`d2 = ${JSON.stringify(d2)}`); console.log(d1);
Copier après la connexion

Maintenant, la ligne 3 de l'intron JS ci-dessus, est le code du programme frère que nous voulions !
Collez le code de chacun comme introns dans l'autre.
Note. Nous devons ajouter d1 + '' dans js pour éviter certaines incohérences de citation

Python: Try it online!

d1 = "print('d1 =', repr(d1)); print('d2 =', repr(d2)); print(d2)"
d2 = "console.log(`d1 = ${JSON.stringify(d1)}`); console.log(`d2 = ${JSON.stringify(d2)}`); console.log(d1 + '');"
print('d1 =', repr(d1)); print('d2 =', repr(d2)); print(d2)
Copier après la connexion

JavaScript: Try it online!

d1 = "print('d1 =', repr(d1)); print('d2 =', repr(d2)); print(d2)"
d2 = "console.log(`d1 = ${JSON.stringify(d1)}`); console.log(`d2 = ${JSON.stringify(d2)}`); console.log(d1 + '');"
console.log(`d1 = ${JSON.stringify(d1)}`); console.log(`d2 = ${JSON.stringify(d2)}`); console.log(d1 + '');
Copier après la connexion

There you go. It's a proper 2nd order QuineRelay! A Python program, that prints a JavaScript program, that prints the original Python program back in a cycle.


Creating a QuineRelay is an exercise in creative coding and understanding how different languages represent and manipulate strings. It involves weaving together introns from various programs, each containing the code to replicate its next neighbour.

At its core, an nth-order relay is a game of n clever ways to escape quotes across n programming languages.

Stay tuned for the next post on MultiQuine!


Sources and references:

  • Ouroboros programs, wiki page.
  • A Third Order Quine in Three Languages, blog by sigfpe.
  • Chain Quine, GitHub repo by Ibragimov Ruslan.
  • 128 Quine Relay, GitHub repo by Yusuke Endoh.
  • QuineRelay: Birth of the Quine serpent, self-referencing blog where a word in each n-order example hyperlinks to the next, cyclically. (May not work in dev.to; checkout the canonical blog)
  • Jörmungandr, wiki page.
  • Ouroboros, wiki page.
  • Art of Code, talk by Dylan Beattie

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:dev.to
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal