Créez un interpréteur pour un faux langage basé sur la pile qui obtient une entrée, l'interprète et génère le résultat sous la forme d'un tableau de nombres. Il doit parcourir chaque octet et exécuter une fonction différente en fonction de ce tableau:
0000 (0): Concaténer (Combiner les deux premiers chiffres d'une pile comme s'il s'agissait d'une chaîne. Ex: 12,5 -> 125)
0001 (1): Incrémenter (Ajouter 1 au numéro en haut de la pile)
0010 (2): décrémenter (soustraire un du nombre en haut de la pile)
0011 (3): multiplier (multiplier les deux premiers chiffres de la pile)
0100 (4): diviser (diviser le nombre du 2e au sommet par le numéro supérieur de la pile)
0101 (5): Ajouter (Ajouter les deux premiers chiffres de la pile)
0110 (6): Soustraire (Soustraire le numéro supérieur de la pile de celui situé en dessous)
0111 (7): Exposant ( Calculez le nombre du deuxième au sommet à la puissance du nombre le plus élevé)
1000 (8): Module: (Trouvez le nombre du deuxième au plus haut modulo celui du haut)
1001 (9): Rotation à droite (Décaler la pile d'une unité. Le numéro en bas est maintenant en haut)
1010 (A): Rotation à gauche (Décaler la pile d'une unité. Le nombre en haut est maintenant en bas)
1011 (B): Duplicate (Copiez le premier numéro pour qu'il apparaisse deux fois. Ex: 4,1 devient 4,1,1)
1100 (C): Double Duplicate (Copiez les deux premiers numéros de la pile. Ex: 4, 1,2 devient 4,1,2,1,2)
1101 (D): échange (échange les deux premiers chiffres de la pile. Ex: 4,1,2 devient 4,2,1)
1110 (E): double Échanger (Échanger les deux premiers chiffres avec deux en dessous d'eux. Ex: 1,2,3,4,5 devient 1,4,5,2,3)
1111 (F): Supprimer / Pop (Supprimer le numéro en haut de la pile)
Par exemple, un fichier contenant
1 1 BC 5 C 5 B 9 5 - Entrée (hex) | | | | | | | | | | 1 2 2 2 4 4 6 6 2 8 - Empiler 2 2 2 2 4 6 6 6 2 2 4 2 4 6 4 2 2 2 2 4 2 2 2 2
produirait [8,6,4,2]
Règles:
- Unicode / symboles sont corrects, mais ASCII est le meilleur.
- Sois créatif! La brièveté compte, mais la créativité est excellente!
- Si les octets sont trop durs, utilisez
"$iv*/+-^%><dtsz."
ou à la"0123456789ABCDEF"
place des octets réels. - LA VITESSE! Plus vite, mieux c'est.
- Le score est basé sur la réputation, mais la taille est un facteur énorme.
Prime:
Essayez de relever ce défi en utilisant votre nouvel interprète le plus court possible.
Remarque:
La chose qui rend cela difficile par rapport à d'autres défis de golf de code, c'est qu'il n'y a pas de code pour passer avec cela. Si, disons, vous deviez écrire un interpréteur brainf * ck, vous pourriez regarder les implémentations d'autres personnes. Avec ça, vous ne pouvez pas faire ça.
J'ai oublié de mettre et de mettre fin à cette date. Je suppose que je vais le faire un mois après avoir créé cela. La personne avec le plus de votes au 22 février gagne!
la source
Réponses:
Ruby, 67 lignes de substitutions d'expression régulière
J'ai décidé d'écrire l'interprète en regex, tout en m'en tenant à des algorithmes efficaces.
J'aurais pu opter pour des octets simples, mais l'utilisation de symboles rend le code plus lisible à mon avis. Bien sûr, si nous pouvions emballer deux instructions dans un octet ...
La concaténation des valeurs négatives entraîne un comportement du complément à dix, reflétant la représentation interne.
La division est une division entière et le reste n'est jamais négatif.
En ce qui concerne le tour de bonus, la solution la plus courte que j'ai trouvée ( 13 caractères ) est une solution propre:
la source
d
(aprèsii
, la pile contient seulement2
, rien avec quoi échanger), et la finale tourne (enfin, au moins la première, la seconde n'est qu'un échange déguisé ... ) doit être à gauche et non à droite.assemblage x86 (sur Win32)
"SPEED!" Semble être extrêmement important ici, et nous savons tous que rien ne vaut le langage de l'assemblage à cet égard. Alors, faisons cela en assemblage!
Il s'agit d'une implémentation du langage en langage assembleur x86 (dans la syntaxe NASM), avec les nombres stockés et interprétés comme des entiers 32 bits non signés, en utilisant directement la pile x86 native. Le sous-dépassement et le débordement de la pile pendant toute opération arithmétique (ou division par zéro) est une erreur d'exécution, mettant fin au programme avec un message d'erreur.
Pour compiler cela, utilisez quelque chose comme
Le programme reçoit le nom du fichier binaire contenant le programme sur la ligne de commande (par exemple
nexlang.exe testprg.bin
). Une fois terminé, il imprime le contenu final de la pile sur une sortie standard dans un format lisible par l'homme.Pour faciliter les tests, enregistrez les éléments suivants dans
nex.def
:Ensuite, écrivez vos programmes NEX («non existants», comme indiqué dans le titre de la question) en utilisant les mnémoniques définies ci-dessus, et compilez avec quelque chose comme
Par exemple, pour le scénario de test d'origine, utilisez ce qui suit
prg.nex
:Et enfin, pour le défi «2014», utilisez le programme NEX 14 octets suivant:
la source
LEA ESI, [ESI+1]
plutôt queINC ESI
?GolfScript, 64 caractères
OK, j'ai donc décidé d'essayer de jouer au golf. Et quel meilleur langage pour le golf que GolfScript?
De manière pratique, GolfScript lui-même est déjà un langage basé sur la pile avec des commandes à un octet et, en l'occurrence, 11 de vos 16 commandes sont directement mappées aux commandes GolfScript intégrées. Donc, tout ce que j'ai vraiment besoin de faire pour interpréter votre langage est d'implémenter les cinq commandes restantes dans GolfScript et de construire une table de traduction:
Le code semble plutôt réparti, car j'utilise des sauts de ligne comme délimiteurs pour la table de traduction. L'initiale
0\
pousse un zéro sur la pile et la déplace sous le programme d'entrée. La{ }/
boucle, comprenant la majeure partie du code, supprime le programme d'entrée de la pile et itère le corps de la boucle sur chacun de ses caractères, et la finale]-1%`
collecte la pile dans un tableau, l'inverse (car votre exemple de sortie commence par le haut de la pile) et le stringifie.Le corps de la boucle commence par une chaîne entre guillemets simples de 16 lignes.
n%
fractionne cette chaîne lors des sauts de ligne,=
recherche la sous-chaîne correspondant au caractère d'entrée et~
évalue la sous-chaîne en tant que code GolfScript.Enfin, voici les implémentations GolfScript des 16 commandes:
`+~
: concatène deux nombres sous forme de chaînes)
: incrément(
: décrémenter*
: multiplier/
: diviser+
: ajouter-
: soustraire?
: monter au pouvoir%
: module](+~
: faire pivoter la pile vers la droite])\~
: faire pivoter la pile vers la gauche.
: dupliquer1$1$
: double doublon\
: échange[@]\+~\
: double échange;
: popJe suis un peu mécontent du double échange - c'est moche et beaucoup plus long que toutes les autres commandes. Il semble qu'il devrait y avoir une meilleure façon, mais si c'est le cas, je ne l'ai pas encore trouvé. Pourtant, au moins ça marche.
Par exemple, exécuter le programme ci-dessus sur l'entrée (donnée sous forme de chaîne entre guillemets GolfScript / Ruby / Perl / Python / etc.):
donne la sortie:
Edit: j'ai réussi à enregistrer deux autres caractères, pour un total de 62 caractères , en utilisant un encodage plus compact de la table de traduction. Cependant, cela sacrifie en quelque sorte la lisibilité:
Les caractéristiques notables de cette version incluent le
(
au début de la boucle, qui décale les indices de commande de 0..15 à -1..14 afin que je puisse mettre la longue séquence de commandes à caractère unique de 1 à 8 au début de la table. Cela me permet de les stocker dans une chaîne distincte et d'éliminer les huit nouvelles lignes les délimitant; hélas, la complexité supplémentaire me coûte ailleurs six personnages.la source
+
en])\+~
Haskell
Juste pour le plaisir, j'ai fait une solution qui n'utilise aucune variable , ne combine que des fonctions.
la source
Rubis,
330316 caractèresJ'ai décidé de jouer au golf. (Parce que c'est toujours amusant.)
La partie principale est la suivante:
Il traduit chaque chiffre hexadécimal en un entier de base 10, puis utilise le
[(huge array of strings)]
pour trouver la bonne chaîne qui représente cette commande. Ensuite, c'esteval
cette chaîne.Notez que cela
%w[x y z]
équivaut à['x','y','z']
.J'aime aussi comment vous pouvez trouver des visages souriants dans cette ligne! Certains d'entre eux sont
:*
:/
:-]
:%
Exemple d'exécution:
la source
C -
642634 caractèresPour le
$iv*/+-^%><dtsz.
dialecte uniquement (ajouteq
comme caractère de fin, avec0
):Solution pour le défi 2014:
dididiizs>
.la source
free(a);
. Et cela ne devrait-il pas figurer<<2
dans lesrealloc
appels?free()
mémoire: Pk, 228
Il y a beaucoup de répétitions dans la mise en œuvre d'instructions similaires, qui peuvent probablement être conçues dans une certaine mesure.
la source
C
924882622603587569562 caractèresAvec les nouvelles lignes évidentes supprimées (conservées pour plus de lisibilité).
Ceci implémente l'interprétation "underflow pushes zero" du commentaire de Jan Dvorak.
La version golfée a en fait changé considérablement par rapport à la version non golfée ici, sous la pression (bienvenue) de la bonne réponse d' Oberon .
J'ai trouvé que le remplacement de la
switch
déclaration en faveur d'uneif
...else
chaîne m'a permis de prendre en compte tous les chiffres de mes cas . Au lieu de cela, il initialise law
variable à 47, donc un incrément la porte à 48 (== ascii'0'
), puis chaque cas incrémentew
jusqu'à ce que nous devions passer'A'
à quel point nous utilisons le premier argument de macro le plus vide qui ajoute un 7 supplémentaire pour se lever. à «A». La version non golfée montre mon préférésbrk
/SIGSEGV
astuce pour obtenir de la mémoire "libre" sans autres allocations.la source
log
n'est même pas défini.R, 428 caractères
Avec indentations:
En action:
la source
JavaScript, 685
Version non golfée ( gist ):
Version golfée:
Exemple:
la source
Haskell
Fonctionnement
la source
tr
?), Cela devient possible.Lisp commun - 589
Accepte l'entrée hexadécimale sans espaces.
Non golfé:
la source
PHP
ce n'est pas le plus joli, mais ça marche.
s'exécute à partir du shell, attend un nom de fichier comme premier argument. il accepte l'un des 3 dialectes (même mixte)
comportement non défini pour les négatifs ou l'index manquant
la source
PureBasic -
2821891 caractèresIl s'agit d'un interpréteur interactif - pas de fichier, vous entrez simplement les codes donnés 0-9, AF, et il exécutera cette commande et s'affichera comme l'exemple de publication l'affiche.
Utilisez "X" ou "Q" pour quitter.
C'était vraiment amusant à faire :)
edit: Après avoir dormi, j'ai pensé que je jouerais au golf - j'ai laissé la version lisible pour référence.
Tout fonctionne de la même manière, sauf que j'ai retiré le Q ou le X pour quitter, fermez simplement la fenêtre pour quitter:
la source
Lisp commun - 586
Non golfé
Lie lexicalement une nouvelle pile dans le code macroexpanded: aucune référence à une variable globale. En outre, il est compilé en code machine.
Exemple
la source
Python 2, 508 octets
Utilise le codage "0123456789ABCDEF". Je suis vraiment fier de la façon dont celui-ci s'est avéré. Il ne lit pas le fichier, il obtient une entrée de STDIN, mais si c'est un problème, il pourrait facilement être modifié.
2 solutions pour le problème 2014:
B11CB3A1AED0A00
(1615 octets) - Concaténateur générique.BB102CD11B513B3622E
(2019 octets) - Beaucoup plus frais - Évalue à (5 * (10-1)) ^ 2-11la source
Python 2, 955 octets
Que fait chaque fonction
la source