Il existe de nombreux défis qui disent "interpréter X", où X est un langage simple. À mon avis, c'est beaucoup trop ennuyeux. Pour donner à toutes les personnes qui procrastinent sur Internet quelque chose d'intéressant à faire, vous pouvez essayer de relever ce défi:
Défi
Choisissez une langue $LANG
. $LANG
peut être n'importe quel langage de programmation complet turing ou un sous-ensemble complet turing d'un langage de programmation. Sachez que si vous omettez une caractéristique de votre langue $LANG
pour l'interprétation, vous ne devez pas non plus l'utiliser pour votre propre programme, car votre soumission doit également être écrite $LANG
.
Écrivez un compilateur / interprète pour l' $LANG
écrire $LANG
. Vous pouvez utiliser toutes les fonctionnalités (y compris eval
et les amis) de votre langue qui sont disponibles pour écrire ce compilateur. Pour rendre la tâche plus difficile, il y a une restriction: votre programme devrait être capable d'interpréter / compiler tous les programmes valides à l' $LANG
exception de votre interprète / compilateur lui-même. S'il se produit que le programme à interpréter / compiler est votre interprète ou compilateur lui-même (quel que soit le nom de fichier), votre programme doit faire quelque chose de complètement indépendant de la fonctionnalité d'un interprète ou d'un compilateur (comme l'écrochage ou l'impression Hello, world!
).
Pour rendre cette tâche encore plus complexe, votre programme ne doit pas lire sa propre source lors de la compilation ou de l'interprétation.
Caractéristiques
- Cette tâche est le golf de code. La soumission avec le moins de caractères qui est correcte gagne. En cas d'égalité, la solution soumise en premier l'emporte.
- Votre programme / script doit lire le programme à interpréter à partir d'un fichier. Vous pouvez coder en dur son chemin et son nom. Lorsque le fichier est lu, vous pouvez soit le compiler dans un autre fichier (qui doit être exécutable sur votre système) soit l'exécuter directement. S'il
$LANG
manque des capacités de lecture de fichiers, vous pouvez choisir une autre façon de lire le code qui convient$LANG
. Vous ne pouvez pas choisir$LANG
comme sous-ensemble d'une autre langue mais avec les capacités de lecture de fichiers supprimées. - Les règles habituelles de code-golf s'appliquent. C'est-à-dire: votre langage personnel que vous avez créé juste pour résoudre ce défi est interdit, si la solution devient triviale en l'utilisant (comme la définition d'un programme à un seul caractère qui implémente exactement la solution). L'abus de règles est encouragé.
la source
Réponses:
Rubis, 63
la source
Perl, 89 caractères, pas de triche
Notez que ce code est extrêmement pointilleux sur ce qui compte comme "lui-même". En particulier, il ne se reconnaîtra pas s'il y a des retours à la ligne de fin ou d'autres espaces blancs supplémentaires dans l'entrée. Pour le tester, enregistrez-le dans un fichier nommé (par exemple)
unquine.pl
et procédez comme suit:Se souvenir du
unquine.pl
fichier doit faire exactement 89 octets, ni plus, ni moins. L'exécuter avec un autre script Perl en entrée exécute simplement l'autre script, comme il se doit:Comme son nom l'indique, l'implémentation est basée sur un quine - en particulier, celui-ci:
Ce code est
$_
égal à lui-même; le reste du programme (qui, bien sûr, doit être dupliqué à l'intérieur$_
) se compare simplement$_
à l'entrée, meurt si elles correspondent et évalue l'entrée autrement.la source
&&
/;
paire par un ternaire (un caractère éteint, doublé par quining). Excellente idée et mise en œuvre!GolfScript, 30 caractères
Ce programme lit le contenu d'un fichier nommé sur la ligne de commande et, s'il n'est pas exactement égal au code ci-dessus, l'interprète comme GolfScript. Si l'entrée est exactement égale au code ci-dessus, elle sera simplement imprimée inchangée (sauf pour une nouvelle ligne ajoutée à la fin).
Il s'agit d'une adaptation assez simple de ce programme d'auto-identification . Plus précisément:
{ }
est un littéral de bloc de code dans GolfScript..~
, appliqué à un bloc de code, duplique le bloc et exécute la copie.À l'intérieur du bloc de code:
`
stringifie la copie du bloc de code.".~"+
y ajoute les caractères.~
, donnant une chaîne contenant le code source du programme."#{$<.read}"
est un hack documenté qui permet l'exécution de code Ruby dans GolfScript. Dans ce cas, il exécute la déclaration Ruby$<.read
(volée sans vergogne à la solution Ruby de Lowjacker ), qui lit et renvoie le contenu de tous les fichiers spécifiés sur la ligne de commande. Ce hack est nécessaire car GolfScript lui-même ne fournit aucune capacité d'E / S de fichier explicite..@
duplique et mélange les éléments au-dessus de la pile afin que la pile contienne deux copies du contenu du fichier suivies du code source de ce programme.=!
compare les deux premiers éléments de la pile (c'est-à-dire le contenu du fichier et la source), renvoyant 1 s'ils sont différents et 0 s'ils sont les mêmes.{~}*
évalue la copie restante du contenu du fichier en tant que code GolfScript, mais uniquement si le résultat de la comparaison est 1. (Techniquement, il exécute le bloc de code{~}
autant de fois que le donne le numéro sur la pile, c'est-à-dire 0 ou 1 fois. À l'intérieur le bloc,~
est l'opérateur eval GolfScript.)Ps. Si la lecture du code à exécuter à partir de stdin est autorisée, ce défi peut être résolu en 21 caractères sans avoir à débourser pour Ruby:
Ce programme lira une chaîne d'entrée depuis stdin et, s'il ne correspond pas à sa propre source, l'exécute (avec une entrée vide). Comme le programme ci-dessus, les entrées qui correspondent à la source sont simplement renvoyées en écho.
la source
Python,
167130118 octetsC'est ma première tentative de golf, alors voilà! Il interprète n'importe quel programme sauf lui-même
Version améliorée:
S'il se récupère alors il barfs avec:
Je pense que cette solution fonctionne à peu près de la même manière que celle d'Ilmari Karonen, l'idée de base est quelque chose comme:
La quine que j'ai utilisée était basée sur celle-ci:
Mais depuis, j'ai réalisé qu'un quine beaucoup plus court est:
Et cela peut être encore plus court si vous autorisez le shell python interactif, auquel cas vous pouvez faire:
Étant donné que python n'a pas un moyen court d'obtenir des arguments de ligne de commande, je suis allé avec raw_input () (qui est encore assez long, mais pas aussi longtemps que
L'utilisation est:
ou
J'ai trouvé un quine plus court à utiliser, mais voici mon ancienne version (pour la postérité):
la source
Je ne peux pas lire exactement à partir d'un fichier en utilisant Javascript (ok, je pourrais, en utilisant la chose HTML5 FileReader, mais cela rend les choses beaucoup plus compliquées que ce dont j'ai besoin). Il s'agit donc d'une fonction qui accepte un programme Javascript en tant que chaîne et l'exécute.
Ce n'est probablement pas aussi golfé qu'il pourrait l'être, mais le voici quand même:
Javascript, 252
Faites-moi savoir si quelqu'un connaît une meilleure technique pour former une quine en Javascript.
la source
45 caractères de sh (shell POSIX). Le code à exécuter doit être dans le fichier
./c
.Le code de l'interprète lui-même doit être dans le fichier
./p
, donc je suppose que j'ai un peu triché, bien que le défi ne semble pas l'interdire. Ou est-ce que cela disqualifierait mon «langage» d'être un «langage de programmation complet»?En utilisant un outil qui est normalement un exécutable externe, mais qui pourrait théoriquement être intégré au shell, le code peut être raccourci:
Cela fait 18 caractères, et le
-s
bit est juste pour supprimer une ligne qui autrement serait toujours imprimée pour les programmes valides (non auto).Et puis, vous pouvez toujours créer une version du langage shell qui fait ce qui précède avec une syntaxe plus concise.
Et puis, vous pouvez toujours créer un programme qui, lorsque l'entrée se compose d'un seul "." --ou l'enfer, la chaîne vide - évalue le contenu d'un autre fichier comme du code normal, et appelle cela un langage de programmation. La chaîne vide serait donc votre solution au défi, dans le langage que vous avez créé. En fait, voici un interprète pour une telle langue:
En utilisant le langage interprété par le script ci-dessus, la solution est la chaîne vide. Et l'emplacement du code n'a plus besoin d'être codé en dur.
Problème?
la source
./othercode
), et ne rien lorsque le code est la chaîne vide. Je n'aurais pas dû appeler le fichier ./othercode, c'est trompeur; c'est juste le code que l'interprète écrit dans le langage de chaîne vide interprétera.JavaScript, 135 caractères
La solution JavaScript de Peter Olson m'a inspiré pour essayer de porter ma solution Perl sur JS. Comme sa solution, ce code définit une fonction
c
qui accepte une chaîne, et l'évale si elle n'est pas égale au code ci-dessus.Il m'a fallu un certain temps pour trouver un bon moyen de faire face à l'absence de délimiteurs de chaînes équilibrés dans JavaScript, jusqu'à ce que je trouve avec le recul la solution évidente:
unescape()
.Idéalement, mon code ne contient aucune barre oblique inverse ni guillemets doubles, il peut donc être stocké en toute sécurité dans des chaînes entre guillemets doubles. Cela permet de tester facilement:
la source
alert()
par0
pour ne rien faire au lieu d'alerterundefined
et enregistrer 13 caractères.p=>...
au lieu defunction c(p)
Lisp commun, 59
sbcl --load
)L
, qui peut compiler des fichiers Common Lisp(L <your file>)
, une erreur est signalée lors de la lecture du fichier.Pourquoi?
Parce que la première fois, vous avez inséré le
:~
mot clé dans*features*
. À présent, votre environnement connaît la~
fonctionnalité et la macro de lecture#+
, lors de l'évaluation de l'~
expression de la fonctionnalité , réussira et lira le formulaire suivant au lieu de la sauter comme elle l'a fait la première fois. Dans votre fichier, le formulaire suivant est#.(#:a)
, qui demande d'évaluer(#:a)
au moment de la lecture et d'utiliser la valeur résultante comme code en cours de lecture. Mais(#:a)
appelle la fonction associée au symbole non interne#:a
. Étant donné qu'il#:a
n'est pas interne, c'est un nouveau symbole qui n'est lié à aucune fonction (c'est-à-dire nonfboundp
). Erreur.la source
Schéma, 48 ou 51 caractères
Scheme est un langage avec de nombreuses implémentations différentes. Malgré les implémentations devant être conformes au dernier RnRS, le dernier standard de travail (R6RS) a été impopulaire en raison de son manque de minimalisme. R7RS sera bientôt publié comme remède, tout en divisant le langage en 2. Le premier langage étant puissant et minimaliste et le second, un sur-ensemble du premier destiné à fournir des extensions de fonctionnalités pour l'interopérabilité entre les implémentations. Jusque-là, nous comptons sur les SRFI (Scheme Requests For Implementation), qui fournissent (si elles sont implémentées dans l'implémentation hôte ou manuellement (comme cela est courant dans le schéma)) un moyen d'accomplir de manière portable des tâches communes. Tout cela pour dire que le premier extrait de code (51 caractères), tout en restant aussi portable que possible, s'appuie sur SRFI-22 (exécutant des scripts de schéma sous UNIX) pour accéder aux arguments de ligne de commande:
ou plus lisible:
Le second (48 caractères) est un moyen d'interprétation sans fichier qui ne peut pas s'évaluer lui-même (dans un environnement nul):
ou plus lisible:
la source
Groovy, 13 octets
Cela devrait interpréter un sous-ensemble de Groovy.
cas de test:
Malheureusement, bien qu'il écorche certainement, il le fait de manière complètement interprétative, et il le fait pour beaucoup d'entrées.
la source
Javascript ES6, 45 octets
Toujours compétitif! (thx @Downgoat)
la source