Une chaîne équilibrée est une chaîne de parenthèses ()
afin que chaque parenthèse puisse être mise en correspondance avec une autre. Plus rigoureusement, ce sont les chaînes couvertes par cette grammaire:
S → (S)S | ε
Nous pouvons transformer une chaîne "à l'envers" en:
Commutation de toutes les occurrences de
(
et)
entre ellesDéplacement des caractères de l'avant de la chaîne vers l'arrière jusqu'à ce que la chaîne soit à nouveau équilibrée.
Faisons un exemple.
Nous commençons par la chaîne équilibrée:
(()(())())
On change ensuite les parens pour faire
))())(()((
Déplacez ensuite les caractères de l'avant de la chaîne vers l'arrière de la chaîne jusqu'à ce que la chaîne soit équilibrée.
))())(()((
)())(()(()
())(()(())
))(()(())(
)(()(())()
(()(())())
C'est notre résultat!
Notez que certaines chaînes peuvent être retournées de plusieurs manières, par exemple la chaîne
(()())
Lorsqu'elle est retournée, elle peut être:
()(())
ou
(())()
Cependant, chaque chaîne a au moins une solution .
Tâche
Écrivez un programme pour prendre une chaîne équilibrée comme entrée et sortie de cette chaîne retournée. Dans les cas où il peut y avoir plusieurs sorties valides, vous n'avez besoin que d'en sortir une seule. Vous pouvez utiliser un autre type d'accolade ( <>
, []
ou {}
) si vous le souhaitez.
Il s'agit d'une compétition de code-golf , vous devez donc viser à minimiser la taille de votre code source, mesurée en octets.
Cas de test
(()()) -> ()(()), (())()
(()(())()) -> (()(())())
((())())() -> (()(()()))
la source
Réponses:
Haskell ,
12412011911711311010910610510410198 bytes4 octets économisés grâce à Bartavelle!
3 octets économisés grâce à Zgarb
1 octet sauvé grâce à Peter Taylor
Voici une solution que j'ai élaborée à Haskell. C'est
ok en ce momentassez bien grâce à l'aide que j'ai reçue, mais je cherche à raccourcir ce point, donc les commentaires / suggestions sont appréciés.Essayez-le en ligne!
Explication
Ce programme définit 4 fonctions, la première
(!)
détermine si une chaîne est équilibrée. Il est défini comme suit:Cette vérification suppose que l'entrée a un nombre égal de parens ouverts et fermés grâce à une suggestion de Peter Taylor.
Le suivant
g
fera tourner la chaîne une fois.Ensuite, nous avons
d
qui prend simplement un paren et le reflèteEnfin, nous avons la fonction qui nous intéresse. Ici, nous utilisons une représentation sans point de
until(!0)g
composée avecmap d
, qui correspondd
à l'entrée et s'appliqueg
jusqu'à ce que le résultat soit équilibré. C'est le processus exact décrit dans la question.la source
g x@(a:b)|x!0=x|1>0=g$b++[a]
et supprimer les parens pourd '('=')'
.d
provoque une erreur de compilation, croyez-moi, j'ai essayé. Mais la première suggestion est la bienvenue. Merci!!
parce que vous n'avez pas besoin de gérer les cas où la chaîne a un nombre inégal de parenthèses ouvertes et fermées, vous pouvez donc échanger les deux premiers cas et avoir_!1=1<0
[]!_=0<1
until
pour raccourcirg
: TIOd
carte'('
vers(-1)
et n'importe quoi d'autre1
, puis les deux cas les plus longs!
peuvent être combinés(i:a)!x=a!(x+i)
. La structure de niveau supérieur doit ensuite être retravaillée pourmap d
entrer dans launtil
condition, et je dois courir, donc je n'ai pas le temps pour l'instant de comprendre quels combinateurs sont nécessaires pour tout coller ensemble.SOGL V0.12 ,
1211 octetsEssayez-le ici!
Explication:
Remarque:
l{
pourrait être remplacé par ( pour 10 octets, mais, malheureusement, il n'est pas implémenté.la source
CJam (20 caractères)
Démo en ligne
ou pour le même nombre de caractères
Démo en ligne
Dissection
Les deux versions ont un en-tête et un pied de page communs
Ensuite, le bit au milieu calcule évidemment jusqu'à quel point il est nécessaire de tourner. Les deux utilisent l'évaluation et dépendent de
(
l'opérateur de décrémentation CJam et de)
l'opérateur d'incrémentation.contre
la source
JavaScript (ES6),
111105 octets(Enregistré 2 octets grâce à @CraigAyre, 2 octets grâce à @PeterTaylor, 2 octets grâce à @Shaggy.)
Non golfé:
Cas de test:
Afficher l'extrait de code
la source
Rétine ,
4638 octetsEssayez-le en ligne! Le lien inclut des cas de test. Edit: 8 octets enregistrés avec l'aide de @MartinEnder. La première étape transpose simplement les parenthèses, tandis que la deuxième étape recherche le suffixe le plus long qui est un préfixe équilibré valide, ce qui est apparemment une condition suffisante pour que la rotation soit entièrement équilibrée. L'équilibrage est détecté à l'aide de groupes d'équilibrage. La construction
((\()|(?<-4>\)))+
correspond à n'importe quel nombre de(
s plus n'importe quel nombre de)
s tant que nous avons déjà<-4>
vu ( ) autant de(
s. Puisque nous ne recherchons qu'un préfixe valide, nous n'avons pas à faire correspondre les)
s restants .la source
((\()|(?<-2>\)))
. Mais votre tentative me inspiré de trouver une approche complètement nouvelle qui sauve deux autres:(?<-1>(\()*\))+
. Cela vous sera certainement utile à l'avenir, alors merci. :)(?<-1>(\()*\))+
fonctionne, car il semble vouloir sortir de la1
pile avant d'avoir réellement correspondu à rien ...\(*
cependant.PHP,
110108 octetsExécuter en tant que pipe avec
-nR
ou tester en ligne .panne
la source
Python 3 ,
112103101 101 octets-2 octets grâce à @ Mr.Xcoder
Essayez-le en ligne!
la source
Octave, 62 octets
Essayez-le en ligne!
Une fonction qui prend la chaîne en entrée et imprime tous les résultats.
Explication:
la source
Mathematica, 78 octets
la source
JavaScript (ES6), 97 octets
Fonctionne en tournant récursivement la chaîne d'entrée jusqu'à ce que sa transposition soit équilibrée, puis en la transposant.
la source
APL (Dyalog Unicode) ,
3530 octetsGolfé une nouvelle approche grâce à @ Adám
Essayez-le en ligne!
Le golf est en cours.
Explication
la source
Python 2 , 99 octets
Essayez-le en ligne!
Sous forme de fonction pour des cas de test faciles:
Python 2 , 108 octets
Essayez-le en ligne!
Cela utilise une approche légèrement différente - au lieu de tourner récursivement la chaîne, si nous considérons les parens comme incrémentant et décrémentant un compteur d'équilibre, une chaîne équilibrée ne doit jamais avoir une somme totale d'incréments - des décréments inférieurs à 0.
Nous prenons donc
inverser les parens:
et le convertir en une liste de sommes d'incréments / décréments:
-3 est le minimum à l'indice 4 (basé sur zéro); nous voulons donc décaler par cet indice + 1. Cela garantit que l'incrément / décrément cumulatif ne sera jamais inférieur à 0; et sera égal à 0.
la source
r=0,
place der=[0]
?r+=[r[-1]+2*b-1]
avecr+=r[-1]+2*b-1,
aussi bienClojure, 118 octets
Renvoie une séquence de caractères, donc je l'appellerais comme ceci:
Retourne d'abord les crochets, puis boucle tant que la somme cumulée du nombre de crochets devient négative à un certain point de la séquence.
la source
brainfuck , 82 octets
Essayez-le en ligne!
Explication
A chaque lecture de caractère, un compteur est modifié comme suit:
)
, le compteur augmente de 1.(
, le compteur diminue de 1, sauf s'il était égal à 0, auquel cas le compteur est inchangé.Chaque préfixe est un suffixe valide d'une chaîne équilibrée (après inversion) si et seulement si ce compteur est 0. Ce code utilise le préfixe le plus long pour former la sortie.
la source