Imprimer des pièces polyglottes

22

En règle générale, les polyglottes sont construites de telle manière que chaque langue peut ignorer des parties du code présentes dans d'autres langues, en les enveloppant dans des chaînes de caractères, en utilisant la syntaxe des commentaires ou d'autres astuces similaires.

Votre objectif est d'écrire un polyglotte où la sortie pour chaque langue est le code du polyglotte qui produit cette sortie. Plus précisément, la sortie doit être construite à partir du code polyglotte avec seulement des suppressions, et elle doit être une quine dans le langage donné.

Règles

  • Seules les quines appropriées sont autorisées (pas de lecture du code source, pas de prise d'entrée, la sortie doit être vers STDOUT ou l'alternative la plus proche si STDOUT n'est pas une option, et les programmes doivent être constitués de plus que des littéraux qui sont implicitement imprimés).
  • Étant donné que différents langages peuvent utiliser différents codages, les octets bruts sont ce qui importe ici. Par exemple, si la langue A utilise UTF-8 et la langue B utilise CP437, le code (hex) C3 88 46 47serait ÈFGpour la langue A et ├êFGpour la langue B.
  • Toutes les sorties doivent être distinctes (encore une fois, en comparant les octets bruts). Cela évite les complications liées à la limitation des versions linguistiques mineures - si deux langues utilisent la même partie du code pour faire la même chose, vous ne pouvez pas les revendiquer toutes les deux.
    • Si vous avez deux langues A et B telles qu'une XYsortie valide dans les deux, mais YZégalement dans B, vous pouvez choisir XYcomme sortie pour A et YZcomme sortie pour B, afin que vous puissiez les revendiquer toutes les deux dans votre score ( mais vous ne pouvez pas réclamer XYpour les deux langues en raison de la règle ci-dessus).
  • Toutes les sorties doivent être aussi courtes que possible. Par exemple, si votre code l'était print('foo')#something, pour Python 3 (en ignorant le fait que la sortie n'est pas correcte), le code que vous auriez besoin de produire serait print('foo')et print('foo')#ne serait pas autorisé. S'il existe plusieurs chaînes de longueur égale (minimale) qui produisent une sortie correcte, vous pouvez choisir l'une d'entre elles.
  • Les soumissions doivent être polyglottes dans au moins 2 langues.
  • Votre score sera donné par (number of programming languages with distinct outputs)**3/(total byte size of polyglot). Le score le plus élevé l'emporte. Dans le cas où deux soumissions obtiennent le même score, la soumission ayant atteint ce score en premier gagnera.
Mego
la source
2
L'avant-dernière règle sonne comme si nous devons prouver qu'il est impossible de jouer au quine résultant plus loin par tout autre ensemble possible de suppressions. Est-ce intentionnel?
Martin Ender
En relation.
Martin Ender
Comment définissez-vous les "suppressions" dans le cas d'un langage dont les commandes ne font pas 8 bits? Supprimez-vous de la source une commande à la fois ou un octet à la fois?
@MartinEnder La bonne foi peut être présumée. À moins que quelqu'un trouve un quine plus court qui peut être formé à partir du polyglotte, la réponse est fiable pour être valide.
Mego
@ ais523 Tout se fait au niveau des octets.
Mego

Réponses:

11

GolfScript + CJam + Fission 2 + Jelly , 4 langues, 24 octets, score 2,667

Commençons par le vidage hexadécimal:

00000000:  3322 3024 700a 2721 2b4f 5222 0a3c 3024 700a 6523 7fff cccc

Pour GolfScript, CJam et Fission 2, nous interprétons cela dans un codage à un octet compatible ASCII comme ISO 8859-1 (le codage exact n'a pas vraiment d'importance, car les langages ne définissent de toute façon que des opérateurs pour les caractères ASCII):

3"0$p
'!+OR"
<0$p
e#<DEL>ÿÌÌ

<DEL> est le caractère de contrôle 0x7f.

Dans Jelly, cela est supposé être dans la propre page de code de Jelly, où cela ressemble à la place:

3"0$p½'!+OR"½<0$p½e#¶”ṘṘ

GolfScript

La edernière ligne est une variable inconnue et #commente le reste de la ligne, donc cela s'imprime

"0$p"
0$p

avec un saut de ligne arrière. Il s'agit de la version polyglotte GolfScript / CJam du quine standard:

".p"
.p

Essayez le polyglotte. | Essayez la quine.

CJam

Ici, e#commente la dernière ligne, donc presque à l'identique, cela imprime

"0$p"
0$p

sans saut de ligne arrière.

Essayez le polyglotte | Essayez la quine.

Fission

Fission ne voit que la deuxième ligne qui est le quine standard de Fission, donc elle imprime

'!+OR"

Je ne peux pas fournir de lien en ligne pour le polyglotte ici, car TIO envoie le fichier à Fission en UTF-8, mais Fission lit l'octet source octet, ce qui rend la dernière ligne trop longue. Cependant, j'ai testé cela localement avec un fichier encodé ISO 8859-1 (dans lequel la dernière ligne a la même longueur que la seconde), pour confirmer que cela fonctionne.

Essayez la quine.

Gelée

Le pilcrow est un alias pour les sauts de ligne dans Jelly, donc la source est équivalente à:

3"0$p½'!+OR"½<0$p½e#
”ṘṘ

Tous, sauf la dernière ligne d'un programme Jelly, sont des "liens auxiliaires" (c'est-à-dire des fonctions) qui peuvent être ignorés à moins qu'ils ne soient appelés, à condition qu'ils soient syntaxiquement valides. C'est en fait la raison pour laquelle la 3première place dans les programmes CJam et GolfScript, car sinon le" ne peut pas être analysé dans Jelly.

Sinon, puisque la fonction n'est pas appelée, le programme n'est équivalent qu'à sa deuxième ligne, qui est le quine Jelly standard.

Essayez le polyglotte. | Essayez la quine.

Martin Ender
la source
9

> <> + Python, 2 langues, 51 46 octets, score ~ ​​= 0,16 0,17

Puisqu'il n'y a pas encore de réponses, je vais commencer par une simple

#.09;!?lo}*2+2f"
_='_=%r;print _%%_';print _%_

Essayez-le pour > <> et Python

Pour> <> la première ligne est un quine (# reflète, "met la ligne entière sur la pile, puis nous poussons 34 (charcode pour") et imprimons tout), l'exécution ne s'en déplace jamais, donc elle ignore efficacement le reste de le code.

Pour Python, la première ligne est un commentaire, tandis que la seconde est un quine (approche standard en python, utilisant la substitution de chaîne avec la même chaîne que les deux arguments).

Leo
la source
1
Une légère adaptation sur la réponse> <> peut vous faire économiser quelques octets: - # "~ r10gol?!; 60. |!
Pélican
@Tealpelican Merci de me rappeler l'utilisation de .! J'ai adapté mon quine en utilisant cette approche, bien que je préfère garder la chaîne à l'envers (car cela économise des octets) et éviter d'utiliser g(car cela pourrait être interprété comme "lire le code source")
Leo
C'est un bon point pour ne pas utiliser g. En y jetant un coup d'œil et en y réfléchissant un peu, vous pouvez le réduire encore plus en utilisant le # (ascii 35) de la pile pour obtenir votre "like; # .09;!? Lo} -1"
Pélican bleu canard
7

JavaScript + Python 2 + Japt, 3 langues, 132 octets, score ~ ​​= 0,205

A="`i96d)p2`i96d)p2";1//2;A=1
S="S=%s;console.log(S,uneval(S))";A//2;S="S=%r;print S%%S";"""
console.log(S,uneval(S))//""";print S%S

Ceci imprime

S="S=%s;console.log(S,uneval(S))";console.log(S,uneval(S))

en JavaScript (uniquement dans Firefox),

S='S=%r;print S%%S';print S%S

en Python 2, et

`i96d)p2`i96d)p2

à Japt. ( Testez-le en ligne! )

Javascript

Voici ce que JavaScript voit:

A="`i96d)p2`i96d)p2";1
S="S=%s;console.log(S,uneval(S))";A
console.log(S,uneval(S))

La première ligne est un no-op car An'est utilisée en aucune façon. La deuxième ligne définit Sla chaîne S=%s;console.log(S,uneval(S))et la troisième l'imprime après avoir remplacé le %spar leuneval représentation ed de S(justeS entre guillemets). Le résultat est une quine en JavaScript.

Python

C'est essentiellement ce que Python voit:

A="`i96d)p2`i96d)p2";1//2;A=1
S="S=%s;console.log(S,uneval(S))";A//2;S="S=%r;print S%%S"
print S%S

La première ligne est à peu près un no-op; la seule partie importante est A=1la fin. Cela se transforme Aen un nombre de sorte que la division entièreA//2 sur la deuxième ligne ne génère pas d'erreur.

La deuxième ligne est essentiellement de la même manière, sauf qu'elle définit Sla chaîne S=%r;print S%%S. La troisième ligne s'imprime Saprès avoir remplacé le %rpar la représentation brute de S(justeS encapsulée entre guillemets simples). Le résultat est une quine en Python 2.

Japt

Voici le code JavaScript que l'interprète Japt voit:

A="`i96d)p2`i96d)p2";1//2;A=1
S="S=%s;console.log(S,uneval(S))";A//2;S="S=%r;print S%%S";"","\nconsole.log(S,uneval(S))//","";.p("r".i("n".t(),S%S))

Comme vous pouvez le voir, c'est essentiellement la même chose que la réponse JavaScript, à une exception près: les deux dernières lignes sont combinées. En conséquence, voici ce que l'interprète voit réellement:

A="`i96d)p2`i96d)p2";1
S="S=%s;console.log(S,uneval(S))";A

La première ligne définit A le quine Japt et la seconde définit Sune partie du quine JS. Dans Japt cependant, seule la dernière expression est envoyée à la sortie; c'est A, donc la sortie est `i96d)p2`i96d)p2.

ETHproductions
la source
Qu'est-ce que c'est uneval? Ne fonctionne pas pour moi
Cyoce
@Cyoce developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… Cela ne fonctionne que dans Firefox.
ETHproductions
3

Jolf +> <>, score = 2 ** 3/15 = 0,533 ....

"r0:g>o<
"Q«Q«

Travailler sur l'ajout d'une autre langue à cela.

Rɪᴋᴇʀ
la source
2

> <>, Python 2 et 3, 3 langues, 107 octets, score = 27/107 ~ = 0,252

#o<}-1:"
a=1/1is 1;b="(_%(_,b))"[a:-a|9];_='a=1/1is 1;b="(_%%(_,b))"[a:-a|9];_=%r;print %s';print (_%(_,b))

Essayez-le en ligne: Python 2 , Python 3 , > <>

La sortie Python 3 est exactement la deuxième ligne, et la sortie Python 2 est cette quine . La sortie> <> est la première ligne.

Explication

Ce programme est basé sur le quine Python 2 classique:

_='_=%r;print _%%_';print _%_

Tout d'abord, pour la rendre compatible avec Python 2 et Python 3, j'ai changé l' printinstruction en appel de fonction et ajouté un espace supplémentaire qui sera utile plus tard:

_='_=%r;print (_%%_)';print (_%_)

Ensuite, j'avais besoin d'un moyen de distinguer Python 2 de Python 3. L'un des moyens les plus simples consiste à tirer parti du fait qu'il /s'agit d'une division entière en Python 2, mais d'une division flottante en Python 3. Ainsi, le code suivant est évalué Trueen Python. 2, mais Falseen Python 3:

1/1is 1

Afin de rendre les sorties distinctes entre les deux langues, j'ai dû supprimer sélectivement les première et dernière parenthèses dans l' printappel (c'est pourquoi j'avais besoin d'espace plus tôt - sans espace, ce ne serait pas une printdéclaration valide en Python 2) . Ainsi, j'avais besoin de modifier le faisceau de quine comme suit:

a=1/1is 1;b="(_%(_,b))"[a:-a|9];_='a=1/1is 1;b="(_%%(_,b))"[a:-a|9];_=%r;print %s';print (_%(_,b))

Cette expression est a:-a|9évaluée à 0:9en Python 2 et 1:-1Python 3. Ainsi, best "(_%(_,b))"en Python 3, mais en Python 2 premiers et derniers caractères sont éliminés, laissant_%(_,b) . Et avec cette modification, le polyglotte était valable pour ce défi.

Comme suggéré par le pélican sarcelle, la quine> <> #o<}-1:"pourrait être ajoutée assez facilement, grâce au fait que #commence un commentaire sur une seule ligne en Python. Il suffit de l'ajouter et une nouvelle ligne ajoute une autre langue et augmente le score de près de dix.

Mego
la source
1

Python 2 + Retina, 2 langues, 55 octets, score = 2 ^ 3/55 ≈ 0,145

J'ai utilisé $nau lieu de les garder tous les deux ASCII valides.

S='S=%r;print S%%S';print S%S#|
#$n\(*S1`$n\(*S1`
#\`#

Python , rétine

Python:

S='S=%r;print S%%S';print S%S

Rétine:


\(*S1`
\(*S1`
mbomb007
la source
0

> <> + Pyke + Python 2, 81 octets, score = 3 ** 3/81 ~ 0,333

"""r00gol?!;60.
a=%r;print a%%a"""#);"34.Cp\D\Es"DEp00/
a=__doc__[-15:]
print a%a

J'ai essayé de faire quelque chose de différent avec toutes les langues.

> <> voit:

"""r00gol?!;60.

Il s'agit d'une légère modification de la norme> <> quine pour utiliser une chaîne entre guillemets triples au début. Cela permet aux triples guillemets de fin pour Python d'être sur une ligne différente.

Essayez-le en ligne!

Pyke voit:

"34.Cp\D\Es"DEp00/

Je n'avais jamais créé de quine à Pyke auparavant et je devais donc y penser. J'ai utilisé des techniques de quining traditionnelles pour créer une chaîne, puis l'évaluer avec elle-même comme entrée. Notez que pour que cela fonctionne sans impact visuel, les avertissements devront être désactivés. Erreurs avec une division par 0 erreur dans l'étape de génération.

Essayez-le ici! Ou tout simplement la partie quine.

Python voit:

Tout ça. Python utilise tout le code pour produire son quine. J'ai décidé d'incorporer la partie quine dans la docstring (bien qu'en fin de compte cela économiserait des octets à supprimer mais je pense que c'est cool). Il s'agit d'une modification de la technique de quining standard.

Essayez-le en ligne!

Bleu
la source