Une chaîne d'accolade est définie comme une chaîne composée des caractères *()[]
dans lesquels les accolades correspondent correctement:
[brace-string] ::= [unit] || [unit] [brace-string]
[unit] ::= "" || "*" || "(" [brace-string] ")" || "[" [brace-string] "]"
Ceci est une chaîne d'accolade valide:
((())***[]**)****[(())*]*
Mais ce ne sont pas:
)(
**(**[*](**)
**([*)]**
Votre tâche consiste à écrire un programme (ou une fonction) qui, étant donné un entier positif n
, prend un nombre en entrée et génère (ou renvoie) toutes les chaînes d'accolade valides de longueur n
.
Caractéristiques
- Vous pouvez sortir les chaînes dans n'importe quel ordre.
- Vous pouvez produire une liste ou une chaîne séparée par un caractère différent.
- Votre programme doit gérer correctement 0. Il existe 1 chaîne d'accolade possible de longueur 0, qui est la chaîne vide
""
. - Il s'agit de code-golf , donc la réponse valide la plus courte - mesurée en octets - l'emporte.
Cas de test
0.
1. *
2. ** () []
3. *** ()* []* (*) [*] *() *[]
4. **** ()** []** (*)* [*]* (**) **() **[] *(*) *[*] (()) ()() ()[] ([]) [**] [()] [[]] []() [][] *()* *[]*
code-golf
balanced-string
Esolanging Fruit
la source
la source
Réponses:
Gelée, 29 octets
-3 octets grâce à @JonathanAllan
Veuillez m'alerter s'il y a des problèmes / bugs / erreurs ou octets que je peux supprimer!
Essayez-le en ligne!
La ou les solutions précédentes que j'avais:
Explication (ma meilleure tentative de description):
la source
“[(*)]”ṗµḟ”*œṣ⁾()Fœṣ⁾[]FµÐLÐḟ
)Prolog, 69 octets
L'une des propriétés les plus intéressantes de Prolog est que, dans de nombreux cas, il est capable d'exécuter un programme à l'envers; par exemple, au lieu de tester pour voir si quelque chose est vrai, vous pouvez générer toutes les solutions pour lesquelles c'est vrai, et au lieu de vérifier la longueur d'une chaîne, vous pouvez générer toutes les chaînes avec une longueur donnée. (Une autre belle propriété de Prolog est qu'il nécessite un espace après la fin de chaque définition de prédicat, et une nouvelle ligne peut être insérée à moindre coût qu'un espace; ainsi, même les programmes joués au golf sont souvent assez lisibles.)
Ce qui précède définit un prédicat (l'équivalent d'une fonction)
b
qui teste pour voir si une chaîne a une longueur donnée et est une "chaîne d'accolade" telle que définie dans la question. Plus précisément, il le fait via le support grammatic / regex / pattern-match de Prolog qui donne un peu de sucre court pour définir ce type d'expression (apparemment, c'est standard / portable, mais je ne le savais pas lors de l'écriture de la réponse, et donc supposait que la réponse ne fonctionnerait que sur une seule implémentation de Prolog; il semble cependant qu'elle fonctionne sur chaque implémentation conforme aux normes). Le programme peut être traduit assez directement en anglais; les deux premières lignes disent "un s est une chaîne vide, ou un e suivi d'un s ; un eest un astérisque, ou un s entre parenthèses, ou un s entre crochets ". La troisième ligne peut être interprétée comme" Le b de N peut être A si A est une liste de longueur N et A est un s suivi d'un null chaîne."Je pris quelques précautions à écrire
s
(et doncb
) afin qu'ils correspondent exactement d' une manière chaque « chaîne de renfort » ( ce qui est la raison pour laquelle les deuxs
ete
doivent exister, plutôt que de les regrouper en un seul prédicat). Cela les rend tous deux entièrement réversibles; ainsib
peut être utilisé pour générer toutes les "chaînes d'accolade" d'une longueur donnée, en plus de tester si une chaîne est une chaîne d'accolade d'une longueur donnée (elle peut également être utilisée dans un troisième sens, pour déterminer la longueur d'une accolade , mais c'est presque certainement son mode de fonctionnement le moins utile). L'implémentation est récursive, par exemple pour générer un s , le code générera tous les e s possibles qui ne sont pas plus longs que la longueur requise de la sortie, et ajoutera tous les s possibless qui leur correspondent dans l'espace restant; parce que j'ai spécifié la longueur de l'argument à l'avance (dans b ), le moteur Prolog sait qu'il ne peut pas générer de sortie plus longue que la longueur donnée, ce qui permet à la récursivité de se terminer.Voici un exemple du programme en fonctionnement:
la source
length
et dans lesappend
deux sens est une partie fondamentale du langage, et les fonctions utilisateur font souvent la même chose.length(A,N)
; siN
est donné etA
ne l'est pas (ce qui se produira si le prédicat est utilisé de la manière demandée dans le programme),length
générera une listeA
composée d'N
éléments inconnus. L'utilisationlength
pour mesurer la longueur d'une liste est probablement plus couramment utilisée (bien que son utilisation "en arrière" soit assez courante dans la programmation Prolog). La plupart des prédicats finissent par fonctionner de la même manière (la seule raison pour laquelle ils ne le sont pas si tenter de les inverser construirait une boucle infinie, ce qui est assez courant).-->
et les DCG en général sont ISO Prolog standard .Haskell,
10194 octets7 octets enregistrés par Zgarb!
Presque simple, suivant la définition, mais avec le
""
cas déplacé.Utilisation:
(Le deuxième calcul prend moins d'une seconde sur une machine lente.)
J'aimerais également partager le résultat d'une autre approche que j'ai imaginée en pensant à générer des fonctions. Il définit une liste
b
de listes de chaînes quib!!n
contient toutes les chaînes d'accolade de longueurn
. De même,u!!n
contient tous les atomes de taillen-1
. Une bonne chose est que le code n'utilise aucun chiffre. Il n'est pas complètement joué au golf :u
ili
pourrait être aligné, et il manque certainement quelques autres opportunités de golf. Malheureusement, il ne semble pas pouvoir être raccourci par rapport à la première version, mais il calculelength $ b !! 10
encore plus rapidement.la source
b$n-k
etb$n-2
. En outre, sur la dernière ligne, vous pouvez fairea:b<-["()","[]"]
et revenira:s++b
.["()","[]"]
mais je ne voyais pas comment améliorer la taille du code avec. Merci!Mathematica, 116 octets
Explication
Trouvez les caractères de la chaîne
"*([)]"
en donnant leList
{"*", "(", "[", ")", "]"}
.Trouvez les tuples de la liste ci-dessus avec la longueur
n
.Fonction booléenne sans nom pour déterminer si le tuple est équilibré:
Supprimer tout
"*"
dans l'entrée.Supprimez à plusieurs reprises toutes les occurrences consécutives de
"("
et")"
ou"["
et"]"
jusqu'à ce que l'entrée ne change pas.Vérifiez si le résultat est vide
List
.Trouvez les tuples qui donnent
True
lorsque la fonction booléenne est appliquée.Convertissez chacun
List
des caractères enString
s.la source
{x=a___,"(",")",y=b___}|{x,"[","]",y}
semble fonctionner.Python 2, 128 octets
Vissez des expressions rationnelles récursives - nous utilisons l'analyseur de Python! Afin de vérifier qu'il s'agit, par exemple, d'
*(**[])*
une chaîne d'accolade, nous procédons comme suit:Créez une chaîne comme
"*", (0,"*","*", [0,0] ,0) ,"*"
, où chaque deuxième caractère sur quatre est un caractère des chaînes d'accolade, et les caractères restants sont collés pour en faire une expression Python potentielle.eval
il.Si cela ne génère pas d'erreur, imprimez
s[1::4]
(les caractères d'accolade).Les caractères de collage sont choisis de sorte que la chaîne que je crée est une expression Python valide si et seulement si la prise d'un caractère sur deux sur quatre donne une chaîne d'accolade valide.
la source
PHP, 149 octets
Utilise le bon vieux générer toute la méthode possible puis filtrer. Utilisez comme:
la source
Python, 134 octets
repl.it
Fonction sans nom qui renvoie une liste de chaînes de longueur valides
n
.Formes toute la longueur
n
tuples des personnages*()[]
, ce qui les rejoint en chaînes en utilisantmap(''.join,...)
et filtres pour ceux qui ont équilibré entre parenthèses en supprimant les « paires »"*"
,"()"
et"[]"
à son tourn
fois et vérifier que le résultat est une chaîne vide (n
temps est surpuissant, en particulier pour"*"
mais est golfeur).la source
Rétine , 78 octets
Le nombre d'octets suppose un codage ISO 8859-1.
Essayez-le en ligne!
Explication
Je génère toutes les chaînes possibles de longueur 5, puis je filtre celles qui ne sont pas valides.
Cela convertit l'entrée en unaire, en utilisant
1
comme chiffre.Cela
+
remplace à plusieurs reprises ( ) le premier (1
) un dans chaque ligne (%
) de telle manière qu'il fait cinq copies de la ligne, une pour chaque caractère possible. Cela se fait en utilisant les substitutions de préfixe et de suffixe,$`
et$'
pour construire le reste de chaque ligne.Cette boucle s'arrête lorsqu'il n'y a plus de 1 à remplacer. À ce stade, nous avons toutes les chaînes de longueur possibles
N
, une sur chaque ligne.Ces deux étapes sont exécutées séparément pour chaque ligne (
%
). La première étape duplique simplement la ligne, avec un;
pour séparer les deux copies.La deuxième étape est une autre boucle (
+
), qui supprime à plusieurs reprises[]
,()
ou*
de la première copie de la chaîne, ou supprime un point-virgule au début de la ligne (ce qui n'est possible qu'après que la chaîne a complètement disparu).Les chaînes valides sont celles qui n'ont plus de point-virgule devant elles, donc nous rejetons simplement toutes les lignes (
A
) qui contiennent un point-virgule.la source
Python 3.5, 146 octets
Très longue par rapport aux autres réponses, mais la plus courte que j'ai pu trouver actuellement. Elle se présente sous la forme d'une fonction lambda anonyme et doit donc être appelée au format
print(<Function Name>(<Integer>))
Sort un ensemble Python de non ordonné chaînes représentant toutes les chaînes d'accolade possibles de la longueur d'entrée.
Par exemple, en supposant que la fonction ci-dessus est nommée
G
, l'appelG(3)
entraînerait la sortie suivante:Essayez-le en ligne! (Ideone)
Cependant, si, comme moi, vous n'êtes pas vraiment fan de simplifier les choses en utilisant Encastrements, alors voici ma originale réponse n'utilisant des bibliothèques externes pour trouver des permutations, et se situe actuellement à un énorme
288237 octets :Encore une fois, comme la réponse concurrente, celle-ci se présente sous la forme d'une fonction lambda et doit donc également être appelée au format
print(<Function Name>(<Integer>))
Et génère une liste Python de chaînes non triées représentant toutes les chaînes d'accolade de la longueur d'entrée. Par exemple, si le lambda devait être appelé en tant que
G(3)
, cette fois, la sortie serait la suivante:En outre, celui-ci est également beaucoup plus rapide que mon autre réponse, étant capable de trouver toutes les chaînes de croisillon de longueur
11
en environ 115 secondes , celles de longueur10
en environ 19 secondes , celles de longueur9
en environ 4 secondes et celles de longueur8
en environ 0,73 secondes sur ma machine, alors que ma réponse concurrente prend beaucoup plus de 115 secondes pour une entrée de6
.Essayez-le en ligne! (Ideone)
la source
05AB1E, 23 octets
Certaines de ces fonctionnalités peuvent avoir été implémentées après la publication de la question. Toutes les suggestions sont les bienvenues!
Essayez-le en ligne!
Comment?
la source
*
également être dans le tableau de suppression? Et leõQ
chèque pourrait-il être remplacé par quelque chose comme NON?'*м„()„[]‚õ:
vs„()„[]‚'*«õ:
(non testé), car il n'y a pas de commande pour concaténer 3 valeurs AFAIK. Le second ne fonctionnera pas car il n'y a pas de NOT qui fonctionnerait comme ça sur une chaîne, AFAIK. (Où AFAIK représente "autant que je sache")