En notation de préfixe, l'opérateur précède les arguments, vous pouvez donc imaginer que l'opérateur appelle next()
ce qui est appelé récursivement. En notation infixe, l'opérateur passe entre les arguments, vous pouvez donc l'imaginer simplement comme un arbre d'analyse. En notation postfixe, l'opérateur vient après les arguments, vous pouvez donc l'imaginer comme basé sur la pile.
Dans la notation anyfix, l'opérateur peut aller n'importe où * . Si un opérateur apparaît et qu'il n'y a pas assez d'arguments, alors l'opérateur attend qu'il y ait suffisamment d'arguments. Pour ce défi, vous devez implémenter un évaluateur anyfix très basique. (Notez que anyfix est un langage récréatif que j'ai abandonné avec lequel vous pouvez jouer ici ou vérifier ici )
Vous devrez prendre en charge les commandes suivantes:
(Arity 1)
- dupliquer
- négatif
(Arity 2)
- une addition
- multiplication
- égalité: retourne
0
ou1
.
Vous pouvez choisir d'utiliser cinq symboles non blancs pour ces commandes. À des fins de démonstration, je vais utiliser "
comme doublon, ×
comme multiplication et +
comme ajout.
Pour les littéraux, vous devez uniquement prendre en charge les entiers non négatifs, mais votre interprète doit pouvoir contenir tous les entiers (dans la plage d'entiers (raisonnable) de votre langue).
Jetons un coup d' oeil à un exemple: 10+5
. Le stockage doit se comporter comme une pile et non comme une file d'attente. Donc, tout d'abord, la pile commence à []
et la liste des opérateurs en file d'attente commence à []
. Ensuite, le littéral 10
est évalué, ce qui fait la pile [10]
. Ensuite, l'opérateur +
est évalué, ce qui nécessite deux arguments. Cependant, il n'y a qu'un seul argument sur la pile, donc la liste des opérateurs en file d'attente devient ['+']
. Ensuite, le littéral 5
est évalué, ce qui fait la pile [10, 5]
. À ce stade, l'opérateur '+'
peut être évalué tel quel, créant ainsi la pile [15]
et la file d'attente []
.
Devrait être le résultat final [15]
pour + 10 5
, 10 + 5
et 10 5 +
.
Jetons un coup d' oeil à un exemple plus difficile: 10+"
. La pile et la file d'attente commencent comme []
et []
. 10
est évalué en premier ce qui fait la pile [10]
. Ensuite, +
est évalué, ce qui ne change pas la pile (car il n'y a pas assez d'arguments) et fait la file d'attente ['+']
. Ensuite, "
est évalué. Cela peut s'exécuter immédiatement, ce qui rend la pile [10, 10]
. +
peut maintenant être évalué de sorte que la pile devient [20]
et la file d'attente []
. Le résultat final est [20]
.
Et l'ordre des opérations?
Jetons un coup d'oeil ×+"10 10
. La pile et la file d'attente commencent à la fois comme []
:
×
: La pile est inchangée et la file d'attente devient['×']
.+
: La pile est inchangée et la file d'attente devient['×', '+']
."
: La pile est inchangée et la file d'attente devient['×', '+', '"']
.10
: La pile devient[10]
. Même s'il×
doit être le premier opérateur à être évalué car il apparaît en premier, il"
peut s'exécuter immédiatement et aucun des opérateurs avant lui, il est donc évalué. La pile devient[10, 10]
et la file d'attente['×', '+']
.×
peut maintenant être évalué, ce qui rend la pile[100]
et la file d'attente['+']
.10
: La pile devient[100, 10]
, ce qui permet+
d'être évaluée. La pile devient[110]
et la file d'attente[]
.
Le résultat final est [110]
.
Les commandes utilisées dans ces démonstrations sont cohérentes avec celles du langage anyfix; cependant, le dernier exemple ne fonctionnera pas en raison d'un bogue dans mon interprète. (Avertissement: Vos soumissions ne seront pas utilisées dans l'interpréteur anyfix)
Défi
Sélectionnez un ensemble de 5 caractères non blancs non numériques et créez un interpréteur anyfix selon les spécifications ci-dessus. Votre programme peut soit sortir le tableau singulier, soit la valeur qu'il contient; il est garanti que la pile de valeurs ne contiendra qu'une seule valeur en fin d'exécution et que la file d'attente des opérateurs sera vide en fin d'exécution.
C'est du code-golf donc le code le plus court en octets l'emporte.
Cas de test
Pour ces cas de test, le doublon est "
, le négatif est -
, l'addition est +
, la multiplication est ×
et l'égalité est =
.
Input -> Output
1+2×3 -> 9
1"+"+ -> 4
2"××" -> 16
3"×+" -> 18
3"+×" -> 36
123"= -> 1 ("= always gives 1)
1+2=3 -> 1
1"=2+ -> 3
1-2-+ -> -3
-1-2+ -> 3 (hehe, the `-1` becomes `+1` at the `-` rather than making the `2` a `-1`)
+×"10 10 -> 200 (after the 10 is duplicated (duplication is delayed), 10 + 10 is performed and then 20 * 10, giving 200)
Règles
- Les échappatoires standard s'appliquent
- Vous pouvez prendre l'interprète officiel anyfix et le jouer au golf si vous le souhaitez. Attendez-vous à perdre horriblement.
L'entrée sera donnée sous forme de chaîne et la sortie sous forme de tableau, un entier unique, en dehors de la représentation sous forme de chaîne de l'un ou l'autre. Vous pouvez supposer que l'entrée ne contiendra que des espaces, des chiffres et les 5 caractères que vous choisissez.
* pas maintenant
la source
0
et1
?×+"10 10
dans les cas de test, ou tout autre exemple, 1) l'utilisation d'un espace blanc et 2) le retard de l'utilisation de l' opérateur en double (deux choses que j'ai complètement manquées).Réponses:
JavaScript (ES6),
204203200 octetsRenvoie un entier.
Caractères utilisés:
+
: une addition*
: multiplication#
: égalitéd
: dupliquer-
: négatifCas de test
Afficher l'extrait de code
Formaté et commenté
la source
-1+-2
. Renvoie 3 au lieu de -3.-
doit être appliqué-1
immédiatement.-
irait avec le2
car il vient après un autre opérateur. Peut-être que @HyperNeutrino peut clarifier. L'opérateur négatif peut être ambigu dans certaines situations.JavaScript (ES6),
162152143150 150 octetsLégèrement non golfé:
Explication
J'utilise
*
pour la multiplication etR
pour la duplication. Les autres opérateurs sont les mêmes que dans la question.N
devient le tableau des nombres (y compris les doublons).Le
replace
gère le cas où le signe négatif vient après le nombre. Par exemple, il passera1-
à- 1
et-1-
à- -1
.Dans le
eval
,s.match
crée le tableau des opérateurs binaires. Notez que cela aura toujours un élément de moins queN
.Le résultat de la fonction est
eval
le mappage des nombres et des opérateurs.Voici ce qui est
eval
édité pour chacun des cas de test:L'opérateur virgule dans une expression JavaScript renvoie le résultat de sa dernière expression, ce qui
map
renvoie automatiquement une expression utilisable.Le
+
signe est nécessaire avanteval
de passertrue
à1
etfalse
à0
.L'utilisation
R
à la fois de la variable et de l'opérateur en double simplifie considérablement lesmap
sous-expressions de.Cas de test:
Afficher l'extrait de code
la source
replace
œuvres aient été conçues. Cela revient3
pour-1+--2
et je pense que ce1
serait correct (les1
changements signent trois fois avant qu'il n'y ait un deuxième argument pour le+
disponible, résultant en-1 + 2
).JavaScript,
321311 octetsEssayez-le en ligne!
Les cinq caractères sont les mêmes que dans la question, sauf
*
pour la multiplication.Le script est compressé à l'aide de RegPack . Le script d'origine est stocké dans la variable
_
après évaluation.la source
-1+-2
. Renvoie 3 au lieu de -3.-3
au lieu de3
?-1 + -2
est-3
, mais doit - il être analysé comme--1 + 2
lieu?3
. Avant2
même de venir sur la pile, la seconde-
est évaluée, et donc nous avons1 2 +
qui l'est en effet3
. Ah, et vous devez probablement aussi modifier votre réponse.Haskell , 251 octets
Essayez-le en ligne! Utilise les caractères suivants:
a
pour l'addition,m
pour la multiplication,q
pour l'égalité,D
pour le double etN
pour la négation. (Je voulais utilisere
pour l'égalité, mais je suis tombé sur le problème quilex
analyse2e3
un nombre.) Exemple d'utilisation:(#([],[])) "2a3 4m"
rendements20
.la source
6502 code machine (C64), 697 octets
Démo en ligne
Utilisation
sys49152
, puis entrez l'expression anyfix et appuyez sur Retour.*
, tous les autres comme suggéré.Voici le code source de l'assembleur de style ca65 lisible .
la source
VB.NET (.NET 4.5)
615576 octets-39 octets grâce à Felix Palmen en passant
\r\n
à\n
Requiert
Imports System.Collections.Generic
(inclus dans le nombre d'octets)Le point d'entrée est Function
A
, qui prend une chaîne en entrée et renvoie aStack(Of Long)
.Symboles:
+
*
=
-
d
Aperçu:
La fonction
A
prend l'entrée et la tokenise. Il utilise unLong?
pour faire un total cumulé pour les entiers à plusieurs chiffres, quiNothing
signifie que nous ne lisons pas actuellement un entier.La sous-routine
E
prend la pile d'entiers et la file d'attente d'opérateurs et évalue la notation anyfix. Il s'appelle récursivement jusqu'à ce qu'il ne reste aucune action.Je déclare les paramètres globaux en une seule fois pour économiser des octets à la fois sur la déclaration et le passage des paramètres.
La valeur de retour de
A
est définie en affectant une valeur à la variable correspondanteA
.VB
True
est équivalent à-1
, de sorte que l'opération doit annuler le résultat pour obtenir la valeur correcte.Essayez-le en ligne!
la source
Imports
, j'obtiens un nombre d'octets de seulement576
- auriez-vous pu mal compté?\r\n
lieu de\n
, c'est donc là que se situe la différence.