Permettez-moi de vous parler d'un système de numérotation simple. (que j'ai compensé juste pour ce défi)
Ce système contient les fonctions ()
, []
, {}
et <>
.
1. ()
Quand ()
aucun argument n'est donné, il est évalué 0
.
Lorsque ()
reçoit un ou plusieurs arguments, il évalue la somme des arguments.
2. []
Quand []
aucun argument n'est donné, il est évalué -1
.
Lorsque []
reçoit un ou plusieurs arguments, il évalue le premier argument moins la somme des autres arguments.
3. {}
Quand {}
aucun argument n'est donné, il est évalué 1
.
Lorsque {}
reçoit un ou plusieurs arguments, il évalue le produit de ces arguments.
4. <>
Quand <>
aucun argument n'est donné, il est évalué 1
.
Quand <>
est donné un ou plusieurs arguments, il évalue le premier entier d'argument divisé par le produit des autres arguments.
Ta tâche
Étant donné une chaîne qui contient un nombre valide (cela signifie que les parenthèses sont équilibrées, pas de division par 0, etc.) dans ce système de numérotation simple, imprimez sa valeur.
Cas de test
() -> 0
(()()) -> 0
([][]) -> -2
({}<>) -> 2
({}[]) -> 0
[] -> -1
[[][]] -> 0
[()<>] -> -1
{()} -> 0
{([]<>)} -> 0
N'oubliez pas qu'il s'agit de code-golf , donc le code avec le moins d'octets gagne.
la source
5/3
,5/-3
,-5/3
et-5/-3
?Réponses:
Dyalog APL , 94 octets
o←{(⊂(1⊃⍵),⍺⍺⊃⍵),2↓⍵}⋄u←{(⊃⍵,⍺⍺1)⍺⍺⍵⍵/1↓⍵}⋄⍎⍕'+/o' '-u+o' '×/o' '÷u×o' '(⊂⍬),'[')]}>'⍳⌽⍞],'⊂⍬'
les usages
⎕IO←0
remplace
)]}>
par un appel de fonction qui prend une pile, applique une opération sur sa trame supérieure, la supprime et ajoute le résultat à sa trame suivante (l'opérateur monadiqueo
est utilisé pour cela; l'opérateur dyadiqueu
gère les cas les plus compliqués de-
et÷
)remplace
([{<
par du code qui ajoute un cadre à la pile ((⊂⍬),
)exécute l'expression résultante (inversée, pour correspondre à l'ordre d'exécution d'APL) avec une pile initiale d'une trame vide (
⊂⍬
)la source
Haskell,
357306277251228224188185180 octetsUn analyseur basé sur des jetons avec une pile explicite.
(%)
prend une pile de jetons et un caractère et pousse (opcode, defaultnumber) ou (0, number) pour({[<
, ou affiche les premiers chiffres et un opcode et pousse la réponse pour)}]>
. Les opcodes sont encodés par un hack d'énumération ascii.Félicitations à @ChristianSievers pour sa grande réponse à laquelle j'ai emprunté quelques idées.
Bon mot!
Maintenant avec moins de gestion des erreurs! Usage:
Merci @ChristianSievers d'avoir économisé 14 + 3 octets!
Merci @Zgarb pour avoir économisé + 4 octets!
la source
(0,[0,0,1,-1,1]!!o):s
en cinquième ligne?!
, afin que vous puissiez faire(s:_)!_=d s
comme le deuxième cas. De plus, je pense que vous pourriez vous lierx<-p$d<$>init a,y<-d$last a
dans le dernier cas de%
.%
vous pouvez déposer des parens autour_:b
etg c
.Python 2,
292265248235223206204 octetsRemplace tous les crochets par un lambda qui fait ce que fait le crochet, puis évalue le code Python résultant. Nécessite son entrée entourée de guillemets, comme
'[<><>([]{})]'
.Ce programme stocke le type de parenthèse en tant que premier caractère de chaque chaîne dans le
for
, et tout ce qui se trouve après le mot-clé enlambda
tant que reste. Il utilise ensuite le premier caractère pour remplacer; le reste est combiné en un lambda(lambda*x:sum(x))()
.Essayez-le sur Ideone!
la source
PEG.js (ES6) , 132 octets
Devrait être corrigé maintenant.
Explication
Plus lisible:
PEG.js est une version étendue de Javascript spécialement conçue pour l'analyse. C'est TRÈS strict, c'est pourquoi j'ai dû utiliser
var
. En outre, il semble y avoir un bogue avec des crochets à l'intérieur des chaînes, qui a considérablement gonflé le code.Pour commencer, nous définissons une règle
x
qui correspond à n'importe quel crocheta
qui peut contenir ou non plusieurs expressions qui correspondent à la règlex
.Pour chaque correspondance à gouverner
x
, nous poussons un 0 dans le tableau de la correspondance interneb
sib
la longueur est 1.Si
b
la longueur est> 0, alors nous trouvons l'index dea
in([<
et obtenons un caractère en+-/
utilisant cet index. Si le résultat n'est pas défini (c'est-à-dire qu'il l'a
était{
), alors nous transformons le résultat en*
. Enfin, nous clouons sur un espace et rejoignonsb
le résultat.Si
b
la longueur est = 0, alors nous trouvons l'index dea
in([<
et obtenons un caractère en10
utilisant cet index. Si le résultat n'est pas défini (c'est-à-dire quia
était{
ou<
), alors nous transformons le résultat en 2. Enfin, nous décrémentons simplement.À la fin, nous pouvons simplement évaluer l'expression et fixer le résultat.
la source
Perl, 113 + 2 = 115 octets
Exécuter avec
-lp
(pénalité de 2 octets).Plus lisible (note: cette "version plus lisible" ne fonctionnera pas réellement, car je mets des commentaires dans des endroits où ils ne sont pas autorisés syntaxiquement):
L'idée de base est que nous convertissons une entrée comme
[()<>]
au programme Perlb(a(0),d(0),0),
via le traitement de texte; Perl est très bien avec la virgule de fin. Plus tôt, nous avons défini les fonctionsa
,b
,c
,d
d'avoir le même effet que le()
,[]
,{}
, des<>
constructions de la langue que nous mettons en œuvre; ils ignorent chacun leur dernier argument (le 0 à la fin), qui est inclus pour s'assurer que toutes les entrées sont analysées correctement, et fonctionnent en utilisant l'implémentation couramment vue dans la programmation fonctionnelle où la tête et la queue sont traitées séparément. Parce queb(e,f,g,0)
signifiee-f-g
, c'est-à-dire traite son premier argument spécialement, alors quea
traite ses arguments symétriquement (a(e,f,g,0)
signifiee+f+g
), nous implémentonsa
récursivement etb
par appela
.c
etd
ont une relation similaire. Ces quatre fonctions sont très similaires, nous les générons donc au moment de l'exécution plutôt que de les implémenter séparément; nous stockons un modèle qui s'applique aux quatre fonctions dans une chaîne, puis générons les fonctions en substituant des caractères dans le modèle.Parce que Perl
/
fait une division en virgule flottante, l'implémenté le{}
fait aussi. Je suppose que ce n'est pas un problème en soi, ou-Minteger
(sélectionner une variante de langage où toutes les opérations arithmétiques sont des opérations entières) est gratuit, car sinon je devrais dépenser des octets supplémentaires pour écrire une division entière en Perl, ce qui ne semble pas être le fond du problème. (Je pense que vous devrez dépenser quatre octets(shift)
pour passer àint+(shift)
; je n'ai pas testé cela.)la source
Octave,
215206198 octetsessayez-le en ligne
la source
PHP,
315300285258250244 octetsremplace les sous-expressions par un soulignement + une valeur; la boucle se casse lorsque l'itération ne fait aucun remplacement.
19 ans depuis ma première rencontre avec C, 17 ans avec PHP;
c'est la première fois que
strtok
cela a du sens ... aider à économiser 24 octets!panne
la source
ES6 (Javascript),
250,171,154,149, 147 octetsUne version Javascript pure.
La «métaprogrammation» (comme la plupart des autres réponses ici), convertit le texte du programme d'entrée en un programme Javascript correspondant, en lui appliquant un certain nombre de substitutions directes de texte (c'est-à-dire en conservant la structure du programme telle quelle).
Peut probablement être joué plus loin.
MISE À JOUR (v2.1)
MISE À JOUR (v2)
Je viens de réaliser que les virgules en attente dans les tableaux ES sont totalement valides, donc tout le code de normalisation des virgules pourrait être supprimé. A également suivi un excellent conseil de @Titus, sur l'optimisation de la recherche alphabétique.
MISE À JOUR (v1)
Suppression de l'alias "remplacer" en double.
MISE À JOUR (v1)
Utilisez un meilleur alphabet: () => 1+ [] => 0 {} => 2 * <> => 2 / (chaque caractère peut être directement réutilisé comme valeur ou opérateur)
Remplace réduire () par remplacer () (mappage alphabétique)
Fusionner le traitement constant des parenthèses en ligne, ouvrir et fermer en une seule étape
Golfé (v2.1)
Golfé (v1)
Golfé (v0)
Expliqué (v0)
Tester
Sortie de test
la source
s.reduce((r,c)=>r+="abcdefgh"["()[]{}<>".indexOf(c)],'')
(-5)? si c'est le cas, vous pouvez vousindexOf
en souvenir dans une variable et prendre l'opérateur d'un troisième littéral de chaîne.Haskell,
184 179 172 161 161 160 159 151 148145 octetsDescente récursive, enfilant l'entrée car Haskell. Comme d'habitude, la dernière ligne n'est pas une définition, mais indique la fonction qui résout le problème. Donc, pour tester, mettez les lignes sauf la dernière dans un fichier, chargez-le et faites quelque chose comme ceci:
Merci à @Zgarb pour l'inspiration et beaucoup de conseils détaillés, et à @Angs pour l'inspiration de sa solution et d'autres conseils.
Il n'a pas été spécifié comment la division devrait se comporter avec des nombres entiers négatifs. Quoi qu'il en soit, une utilisation répétée
div
semble incorrecte, car ce n'est pas la même chose qu'une utilisationdiv
avec le produit des valeurs restantes. Maintenant, en utilisantquot
, j'obtiens les mêmes résultats pour<{}([][])[]>
et<{}{([][])[]}>
.Pour un code agréable et presque lisible, regardez la première version. Les versions intermédiaires contiennent toutes sortes de code agréable et intimidant et aident à comprendre cette version.
la source
(!)=(,)
et en utilisant!
au lieu de tuples explicites.m x
et end x
tant que1#x
et0#x
, vous pouvez fusionner les casm[x]
etd[x]
en un seul, ce qui, je pense, économise également quelques octets.!
astuce ne paie pas. Ta deuxième suggestion est diabolique, voilà mon code presque lisible ... Intelligent!s%(c:i)=(s?c,i)
ets?')'=sum s
etc. sera beaucoup plus court, car vous pouvez vous débarrasser desi
s répétés . ..Attendez, cela ne fonctionnera probablement pas à cause de l's%(_:i)
affaire.elem
etdiv
cela devrait économiser encore plus d'octets.JavaScript (ES6), non
eval
, 156 octetsExplication: L'expression régulière trouve le premier crochet de fermeture non traité et fait correspondre (vraisemblablement) le crochet d'ouverture correspondant et tout argument intermédiaire. Les arguments sont divisés et réduits en fonction de l'opération (malheureusement '(' et '[' ne sont pas la paire optimale pour
+
et-
), ou s'il n'y a pas d'arguments, la valeur appropriée est calculée (encore une fois, la correspondance des caractères aux valeurs n'est pas optimale) de mon point de vue). Le résultat est ensuite remplacé par un espace de tête afin de le séparer des autres résultats. La fonction s'appelle alors récursivement jusqu'à ce qu'il n'y ait plus de modifications à effectuer, auquel cas elle renvoie la valeur résultante. Exemple:la source