Écrivez un programme qui accepte une chaîne de quatre caractères ()[]
qui satisfait ces points:
- Chaque parenthèse gauche
(
a une parenthèse droite correspondante)
. - Chaque support gauche
[
a un support droit correspondant]
. - Les paires de parenthèses et de parenthèses correspondantes ne se chevaucheront pas. eg
[(])
n'est pas valide car les crochets correspondants ne sont pas entièrement contenus dans les parenthèses correspondantes, ni vice-versa. - Le premier et le dernier caractère sont une paire de parenthèses ou de crochets correspondants. Donc
([]([]))
et[[]([])]
sont valides mais[]([])
ne le sont pas.
(Une grammaire pour le format d'entrée est <input> ::= [<input>*] | (<input>*)
.)
Chaque paire de parenthèses et de crochets correspondants correspond à un entier non négatif:
- Les valeurs des paires entre parenthèses correspondantes sont toutes additionnées . La correspondance vide
()
a une valeur0
. - Les valeurs des paires entre parenthèses correspondantes sont toutes multipliées . La correspondance vide
[]
a une valeur1
.
(La somme ou le produit d'un nombre est ce même nombre.)
Par exemple, ([](())([][])[()][([[][]][][])([][])])
peut être décomposé et évalué comme 9
:
([](())([][])[()][([[][]][][])([][])]) <input>
(1 (0 )(1 1 )[0 ][([1 1 ]1 1 )(1 1 )]) <handle empty matches>
(1 0 2 0 [(1 1 1 )2 ]) <next level of matches>
(1 0 2 0 [3 2 ]) <and the next>
(1 0 2 0 6 ) <and the next>
9 <final value to output>
Un autre exemple:
[([][][][][])([][][])([][][])(((((([][]))))))] <input>
[(1 1 1 1 1 )(1 1 1 )(1 1 1 )((((((1 1 ))))))]
[5 3 3 (((((2 )))))]
[5 3 3 ((((2 ))))]
[5 3 3 (((2 )))]
[5 3 3 ((2 ))]
[5 3 3 (2 )]
[5 3 3 2 ]
90 <output>
Votre programme doit évaluer et imprimer l'entier représenté par la chaîne d'entrée entière. Vous pouvez supposer que l'entrée est valide. Le code le plus court en octets gagne.
Au lieu d'un programme, vous pouvez écrire une fonction qui prend une chaîne et imprime ou renvoie l'entier.
code-golf
arithmetic
balanced-string
recursion
Loisirs de Calvin
la source
la source
Réponses:
CJam, 23
Avec de GRANDS crédits à Dennis! Essayez-le en ligne
Explication:
Le programme convertit l'entrée en une expression CJam puis l'évalue.
[…]
devient[…1]:*
(ajouter 1 et multiplier)(…)
devient[…0]:+
(ajouter 0 et ajouter)la source
q"])(""1]:*0]:+["4/ers~
Lisp commun - 98
(
par(+
[
par(*
]
par)
Cela nécessite que la
cl-ppcre
bibliothèque soit chargée dans l'image lisp actuelle.Explication
Les fonctions
*
et+
sont variadiques et renvoient leur valeur neutre lorsqu'aucun argument n'est donné. Pour vos exemples, la forme lisp évaluée est la suivante:et
Sans regexes - 183 octets
C'mon, Lisp - 16 octets (expérimental)
Les autres langues sont tellement laconiques que je suis tenté de créer mon propre langage de golf basé sur Common Lisp, pour des manipulations de cordes plus courtes. Actuellement, il n'y a pas de spécification et la fonction eval est la suivante:
Tests:
s
et deux piles,p
etq
.p
.<
: sortp
et pousse versq
.r
: remplace danss
(doit être une chaîne) des caractères dansq
les caractères dansp
; le résultat est stocké danss
;p
etq
sont vidés.R
: lire à partir d'une chaînes
, stocker le résultat dans une variables
.E
: formulaire evals
, stocker le résultat danss
.la source
Pyth,
353433 octetsManifestation.
1 octet grâce à @Jakube.
Nous commençons par analyser l'entrée. Le format d'entrée est proche de Python, mais pas tout à fait. Nous avons besoin de virgules après chaque groupe entre parenthèses ou entre crochets. La virgule à la fin d'un groupe entre crochets est inutile, mais inoffensive. Pour ce faire, nous utilisons ce code:
Cela laissera un extra
,
à la fin de la chaîne, ce qui enveloppera tout l'objet dans un tuple, mais cela est inoffensif, car le tuple sera additionné, et aura donc une valeur égale à son élément.Maintenant que la chaîne est analysée, nous devons trouver sa valeur. Cela se fait à l'aide d'une fonction définie par l'utilisateur
y
, qui est appelée sur l'objet analysé. la fonction est définie comme suit:la source
Emacs lisp, 94
Le format est très vif, j'ai donc pensé qu'une simple transformation pourrait fonctionner:
Le format intermédiaire ressemble à quelque chose (pour l'exemple de la question):
Nous sommes aidés par le fait que l'addition et la multiplication font déjà ce que nous voulons avec une liste d'arguments vide.
Dégolfé et interactif, pour vous faire plaisir:
la source
interactive
(au lieu de buffer-string, utilisez read-from-string).Rétine , 111 octets
Donne la sortie en unaire.
Chaque ligne doit aller dans son propre fichier mais vous pouvez exécuter le code comme un seul fichier avec l'
-s
indicateur. Par exemple:L'explication vient plus tard.
la source
Java, 349 caractères
Une approche récursive simple. Attend que la chaîne soit le premier argument utilisé pour appeler le programme.
Étendu:
la source
Perl 5, 108
Fait en tant qu'interprète plutôt que de réécrire et d'évaluer. Pas une grande projection, mais amusant à écrire quand même.
Non-golfé:
la source
Python, 99
J'ai essayé une variété de méthodes, mais la plus courte que j'ai pu obtenir était essentiellement un remplacement et une évaluation. J'ai été agréablement surpris de constater que je pouvais laisser tous les
,
s[1,2,]
finaux , car Python peut analyser et la virgule finale finale met juste le tout dans un tuple. La seule autre partie non simple serait laord(c)%31%7
pour séparer les différents personnages (il évalue à2
,3
,1
,0
pour(
,)
,[
,]
respectivement)la source
Java, 301
une approche un peu différente de la réponse de TheNumberOne, bien que la mienne soit également de nature récursive. L'entrée provient de la ligne de commande. La méthode void enregistre quelques octets lors de la suppression des caractères qui ne sont plus nécessaires.
étendu:
la source
Python,
117110109 octetsUn aspect avec lequel je me débattais est que la fonction a essentiellement deux valeurs de retour: le produit / somme et la nouvelle position dans la chaîne. Mais j'ai besoin d'une fonction qui ne renvoie que le résultat, donc retourner un tuple ne fonctionne pas. Cette version utilise un argument "référence" (liste avec un élément), pour retransmettre la position de la fonction.
J'ai une version plus courte (103 octets) qui utilise une variable globale pour la position. Mais cela ne fonctionnera que lors du premier appel. Et une fonction qui ne fonctionne qu'une seule fois semble un peu louche. Je ne sais pas si ce serait acceptable pour le golf de code.
L'algorithme est une récursivité simple. J'ai essayé un certain nombre de variantes pour l'expression qui met à jour le produit / somme. J'ai proposé quelques versions qui étaient exactement de la même longueur, mais aucune n'était plus courte.
Je m'attendais en quelque sorte à ce que l'approche qui transforme cela en une expression qui soit évaluée gagnerait probablement. Mais comme on dit: "Itérer est humain, récuser divin".
la source
Clojure - 66 octets
Notez qu'il
([] (()) ([] []) [()] [([[] []] [] []) ([] [])])
s'agit d'un formulaire Clojure valide. Donc:g
.g
fonction locale s'applique+
ou*
au résultat de l'invocation deg
sur des sous-éléments de ses arguments.x
dans une séquence vide;(map g x)
renvoienil
etapply
renvoie la valeur neutre de l'opération.la source
JavaScript (ES6), 116 octets
la source