Le défi
Dans ce défi, vous spécifiez une langue source S
et une langue cible T
. Votre tâche consiste à écrire le programme suivant P
dans la langue S
. Si un programme valide Q
dans la langue T
est donné en entrée P
, il affichera un programme valide R
dans la langue T
qui ne prend aucune entrée et ne sort pas Q(R)
, c'est-à-dire le programme Q
appliqué au code source de R
. De plus , vous devez présenter dans votre réponse un exemple de programme non trivial Q
(le plus intéressant, le meilleur, bien que vous ne marquiez aucun point pour cela), le programme résultant R
et la sortie de R
. C'est le code-golf, donc le code le plus court pour les P
victoires.
En d'autres termes, il s'agit d'un défi d'écrire un "constructeur de quine universel" qui peut créer des types arbitraires de quines généralisés.
Clarifications
- Vos langues source et cible peuvent être identiques.
- Le programme
P
doit prendre une chaîne en entrée (depuis STDIN ou équivalent) et produire une chaîne (vers STDOUT ou équivalent), comme tout programme de sortieR
. - Les programmes d'entrée
Q
doivent également transformer une chaîne en une autre chaîne, mais leur forme est plus flexible: il peut s'agir de fonctions chaîne à chaîne, d'extraits de code qui modifient une variable avec un certain nom, d'extraits qui modifient la pile de données si votre langue cible en a un, etc. Vous pouvez également restreindre davantage la forme desQ
en indiquant que, par exemple, ils ne peuvent contenir aucun commentaire. Cependant, vous devez être en mesure d'implémenter n'importe quelle fonction chaîne à chaîne calculable en tant que programme d'entréeQ
, et vous devez indiquer explicitement comment ils fonctionnent et quelles contraintes supplémentaires vous leur imposez. - Le programme de sortie
R
doit vraiment être un quine (généralisé), il ne doit donc lire aucune entrée (entrée utilisateur, fichiers, etc.) saufQ
si c'est le cas. - Les failles standard ne sont pas autorisées.
Un exemple
Supposons que je choisis Python comme langue source et Haskell comme langue cible, et que je demande en outre que le programme d'entrée soit une définition sur une ligne d'une String -> String
fonction nommée f
. Si je donne le programme d'inversion de chaîne
f x = reverse x
en entrée de mon programme Python P
, il affichera le code source d'un autre programme Haskell R
. Ce programme imprime dans STDOUT le code source de R
, mais inversé. Si P
reçoit la fonction d'identité
f x = x
en entrée, le programme de sortie R
est une quine.
Expressions Haskell → Expressions Haskell, 41 octets
Essayez-le en ligne!
Comment ça fonctionne
P $ "Q"
=((++)<*>show).('(':).(++")$(++)<*>show$") $ "Q"
construit"R"
par(++")$(++)<*>show$")
: ajout de la chaîne")$(++)<*>show$"
,('(':)
: ajouter le caractère au début'('
, et(++)<*>show
(=\x->x++show x
): en ajoutant une version citée de cela,résultant en
"R"
="(Q)$(++)<*>show$\"(Q)$(++)<*>show$\""
.R
=(Q)$(++)<*>show$"(Q)$(++)<*>show$"
fonctionne par"(Q)$(++)<*>show$"
,(++)<*>show
: en ajoutant une version citée de cela,Q
à cela,résultant en
Q "(Q)$(++)<*>show$\"(Q)$(++)<*>show$\""
=Q "R"
.(Les parens autour
Q
sont nécessaires car ilsQ
peuvent contenir$
aussi facilement queR
cela et$
malheureusement, ils sont associatifs à droite.)Démo
la source
$
besoin des parenthèses, mais aussi de fuitelet
,do
ou des expressions lambda.let
/if
/case
/do
si je ne les émets pas moi-même. C'est peut-être aussi bien que je n'étais pas obligé de le faire.Source = Cible = JavaScript, 66
Hypothèses pour Q:
Q
doit être une fonction anonyme JavaScript chaîne à chaîne.Exemples:
function(s) { return s.split('').reverse().join(''); }
Dans ce cas,
P(Q)
(ouR
) sera:,function a(){console.log(function(s) { return s.split('').reverse().join(''); }(a+'a()'))}a()
et en l'exécutant, nous obtiendrons:)(a}))')(a'+a(} ;)''(nioj.)(esrever.)''(tilps.s nruter { )s(noitcnuf(gol.elosnoc{)(a noitcnuf
qui est exactement le même queQ(R)
.function(s) { return s; }
dans ce cas,
P(Q)
(ouR
) sera:function a(){console.log(function(s) { return s; }(a+'a()'))}a()
qui est une Quine JavaScript . Inutile de dire que ceQ(R)
sera la même chose, puisque Q est la fonction d'identité.Quelques notes:
STDIN en JavaScript est traditionnellement
prompt()
, cependant, je me suis permis de m'abstenir de la tradition dealert()
STDOUT, afin de faciliter le processus de sortie en tant que programme utilisant le copier-coller. (Je me rends compte que je peux enregistrer jusqu'à 12 caractères lors du passage àalert()
).Je peux également raccourcir les choses dans ES6, mais je veux rester avec JavaScript natif pour l'instant. J'envisage de soumettre une réponse S = Scala, T = ECMA6 à l'avenir, juste pour l'expérience.
Je réalise également que JavaScript ne peut presque jamais battre CJam en code-golf , mais j'ai dû relever ce défi! C'était sûrement amusant.
la source
Gelée → 7 , 9 octets
Essayez-le en ligne!
Q est une fonction 7 (c'est-à-dire qui ne regarde pas au-delà de l'élément supérieur de la pile et effectue des E / S via la pile) et est donnée comme argument de ligne de commande.
Explication
Le programme 7
Le constructeur de quine universel dans 7 que j'utilise ici est:
La première chose à noter est que le 7 en tête est l'équivalent du premier espace et n'a aucun effet sur le programme. La seule raison pour laquelle il existe est d'obéir aux règles de PPCG contre les quines uniquement littérales (il est codé par le second
1
dans le programme plutôt que lui-même).Le reste du programme est un élément de pile unique (il a équilibré
7
s et6
s), qui fait ce qui suit lors de l'exécution:En d'autres termes, cet élément de pile est un programme qui imprime le haut de la pile, avec
7
préfixé, au format de sortie 7 (ce qui signifie "imprimer littéralement, en utilisant le même codage que le code source", et est donc clairement le meilleur codage pour quines). Il est assez heureux ici que nous puissions réutiliser le littéral7
à deux fins (le format de sortie et le premier espace blanc.) De toute évidence, en insérant quelque chose juste avant la finale3
, nous pouvons produire une fonction de7
+ l'entrée, plutôt que de simplement sortir7
et entrée directement.Comment cet élément de pile obtient-il son propre code source? Eh bien, lorsque la fin du programme est atteinte, 7
eval
s l'élément de pile supérieur par défaut. Cependant, il n'est pas réellement sorti de la pile dans le processus, donc le littéral d'élément de pile qui a étéeval
mené est toujours là. (En d'autres termes, le programme ne lit pas sa propre source - comme en témoigne le fait qu'il est incapable de voir le7
au début du programme, qui est un séparateur d'éléments de pile plutôt qu'une partie d'un littéral - mais plutôt, il se compose principalement d'un littéral qui esteval
dirigé par défaut.)Le programme Jelly
C'est peut-être l'un des programmes Jelly les moins jelly que j'ai écrits; il se compose de trois nilads (
“ṚƓ^ṾṂ’
,³
,3
), qui sont juste en sortie car aucune séquence les opérations sont effectuées sur eux. Le3
est assez évident, juste être une constante entière. Ce³
est aussi simple si vous connaissez Jelly: c'est la notation explicite de Jelly pour le premier argument de ligne de commande (qui est l'endroit où Jelly prend généralement son entrée). Le reste du programme Jelly représente la majeure partie de mon constructeur universel de quine 7: en exploitant le fait que toutes les commandes de 7 peuvent être représentées à l'aide de chiffres ASCII, nous pouvons interpréter717162234430
non pas comme une série de commandes, ou même comme un nombre octal (comme c'est conceptuellement), mais comme un nombre décimal, ce qui signifie que nous n'avons pas besoin d'un formatage spécial pour la sortie. Ce nombre décimal devient“ṚƓ^ṾṂ’
dans la notation entière compressée de Jelly.Exemple
Si nous donnons
24053
comme programme Q, nous obtiendrons la sortie suivante:Essayez-le en ligne!
2405
concatène l'élément de pile supérieur à lui-même:(La dernière étape peut sembler un peu déroutante; ce qui se passe est que l'échappement d'un élément de pile convertit chaque commande qu'il contient de "exécuter cette commande" en "ajouter cette commande en haut de la pile", donc chaque commande s'ajoute à l'original l'élément supérieur de la pile pendant son exécution.)
En tant que tel, l'exécution du programme résultant R nous donne deux copies de R:
la source
CJam → CJam, 13 octets
Essayez-le en ligne!
L'entrée
Q
doit être un extrait de code qui modifie la seule chaîne de la pile.Q
est lu depuis stdin.Exemple
Contribution:
Il ajoute un espace entre tous les deux caractères et inverse la chaîne.
Production:
Sortie du quine généralisé:
Explication
Il évalue d'abord le quine, afin que nous puissions obtenir sa représentation sous forme de chaîne sans guillemets inutiles. Remplacez ensuite la charge utile par l'entrée.
Cela pourrait être l'
{`"_~"+ }_~7qt
endroit où l'espace est l'espace réservé de la charge utile. Mais changer la charge utile pour7
économiser un octet.la source
Fusain → Perl (5),
2933 octetsEssayez-le en ligne!
Le programme Perl Q doit renvoyer un extrait qui prend l'entrée sous forme de chaîne à sa droite et fournit une sortie dans la variable
$_
. (Les fonctions Perl arbitraires peuvent être converties dans ce formulaire en les encapsulant commesub x {…}; $_=x
. Dans la plupart des cas, cependant, la syntaxe de Perl signifie qu'aucun encapsulage n'est requis.)Explication
Le Perl
Voici à quoi ressemble le constructeur de quine universel Perl:
(Dans la plupart des cas, vous voudrez jouer au golf
$_=q(say…"\$_=q($_);eval");eval
, mais je ne suis pas sûr que vous puissiez insérer du code Perl arbitraire dans le…
.)En d'autres termes, nous avons un wrapper extérieur
$_=q(…);eval
qui attribue une chaîne à$_
, puis l'évalue. À l'intérieur de l'emballage"\$_=q($_);eval"
, c'est-à-dire une reconstruction de l'emballage avec son contenu via l'utilisation de la valeur que nous avons stockée dans$_
, plus le code Q spécifié par l'utilisateur, plusprint
pour imprimer la sortie. (Malheureusement, nous ne pouvons pas l'utilisersay
; cela ajoute une nouvelle ligne, et c'est pertinent dans les quines.)Le charbon de bois
Le "point" de cette réponse était de produire des quines généralisées en Perl, donc une fois que j'ai eu une stratégie de golf pour le faire (celle que j'ai utilisée dans de nombreuses autres réponses), il était temps d'écrire le programme P, qui ne fait que remplacer une chaîne dans un modèle. Ce que je voulais ici, c'était un langage qui était bon pour imprimer des chaînes constantes (idéalement les compresser un peu), et pour y interpoler les entrées utilisateur.
Après avoir essayé quelques-uns, je me suis installé sur Charcoal, que je n'ai jamais utilisé auparavant (et qui pourrait vraiment faire avec de la documentation); il est conçu pour l'art ASCII mais capable d'écrire des chaînes dans une dimension aussi. Les caractères ASCII sont imprimés littéralement dans Charcoal, ce qui signifie que l'impression de chaînes constantes ne prend pas de passe-partout, et nous pouvons utiliser la
S
commande pour interpoler une chaîne prise à partir de l'entrée utilisateur dans le programme.Il est cependant possible d'aller (légèrement) plus court. Le constructeur de quine universel Perl contient deux sections répétées assez longues. Nous pouvons donc utiliser la
A
commande pour les affecter à des variables (par exemple, desA…α
assignations à la variableα
), et simplement interpoler les variables dans la chaîne que nous imprimons en utilisant leurs noms. Cela économise quelques octets sur l'écriture littérale de la chaîne.Malheureusement, Charcoal ajoute également une nouvelle ligne au programme, mais ce n'est pas une grosse affaire; il en coûte simplement deux octets à an
\n
pour ajouter cette nouvelle ligne à l'entrée de Q également.Exemple
Si nous donnons l'entrée
$_=reverse
(qui inverse une chaîne), nous obtenons la sortie suivante:Essayez-le en ligne!
qui est un quine-like qui imprime sa source à l'envers, comme prévu.
la source
Gelée → Sous - charge , 15 octets
Essayez-le en ligne!
Prend la fonction de sous-charge d'entrée Q comme un argument de type commande. Q doit prendre l'entrée de la pile et pousser la sortie vers la pile, sans tenter d'inspecter les éléments de pile plus profonds (car ils n'existeront pas).
Explication
La sous-charge
Le constructeur de quine universel Underload utilisé ici est:
La plupart du programme est un seul littéral. Nous suivons cela par
:^
, qui le copie, puis évalue une copie (en laissant l'autre copie sur la pile).Lorsque le littéral commence à évaluer, nous exécutons
a
(escape, qui le ramène sous la même forme que le programme original A), et(:^)*
(qui s'ajoute:^
), reconstruisant ainsi le code source du programme entier. Nous pouvons ensuite exécuter la fonction Q pour transformer cela de manière arbitraire et imprimer le résultat avecS
.La gelée
Je ne peux pas utiliser Charcoal cette fois car un interpréteur de validation de sous-charge se bloque à la fin du programme si le programme se termine par une nouvelle ligne. (Certains interprètes de sous-charge, comme celui sur TIO, n'appliquent pas cette règle, mais je voulais être correctement portable.) Malheureusement, Charcoal ajoute naturellement des nouvelles lignes à sa sortie. Au lieu de cela, j'ai utilisé Jelly, qui est presque aussi laconique dans des cas simples comme celui-ci; le programme se compose d'une liste littérale avec deux éléments (
““”
), et les joint sur l'entrée (j
), interpolant ainsi l'entrée utilisateur dans le programme.Exemple
En utilisant l'entrée
:S^
(imprimer une copie, puis évaluer l'original), nous obtenons le programme Underload suivant:Essayez-le en ligne!
Cela s'imprime infiniment de fois, d'une manière assez intéressante: après avoir fait le comportement normal de quine, il s'exécute ensuite
eval
sur une copie de ce qu'il a sorti. Cela provoque le programme reconstruit entier pour s'exécuter à nouveau, indéfiniment (Underload est récursif de queue). Quining et faire uneval
est en fait la seule façon de faire une boucle infinie dans Underload.la source
RProgN 2 , 11 octets
Explication du programme
Quine Explication
Le quine qui est produit est simple, mais utilise la fonctionnalité de gestionnaires de fonctions inégalés dans RProgN2 pour créer un quine court et doux, appelé quine "Looping". C'est un concept étonnamment similaire à un <> <quine.
Bien sûr, en raison de la structure de ce quine, tout sauf les vrais no-ops (qui ne sont pas stringifiés) peuvent être placés après la fonction de concaténation, et
Quelques quines
{`{.i}{
: Sorties{}i.{`{
.i
est juste la fonction "inverse", donc ce programme sort lui-même inversé.{`{.S§.}{
: Sorties..S`{{{}§
.S
convertit la chaîne en une pile de caractères,§
trie la pile lexographiquement, puis la.
rassemble à nouveau, sortie elle-même triée.Essayez-le en ligne!
la source