Uma cadeia equilibrada é uma cadeia de parênteses ()
para que todos os parênteses sejam encontrados com outro. Mais rigorosamente, são as cadeias abrangidas por esta gramática:
S → (S)S | ε
Podemos transformar uma string "de dentro para fora":
Alternando todas as ocorrências
(
e)
entre siMovendo caracteres da frente da string para trás até que a string seja equilibrada novamente.
Vamos fazer um exemplo.
Começamos com a string balanceada:
(()(())())
Em seguida, trocamos os parênteses para fazer
))())(()((
Em seguida, mova os caracteres da frente da cadeia para a parte de trás da cadeia até que ela esteja equilibrada.
))())(()((
)())(()(()
())(()(())
))(()(())(
)(()(())()
(()(())())
Esse é o nosso resultado!
Observe que algumas seqüências de caracteres podem ser viradas do avesso de várias maneiras, por exemplo, a sequência
(()())
Quando virado do avesso, pode ser:
()(())
ou
(())()
No entanto, cada string tem pelo menos uma solução .
Tarefa
Escreva um programa para pegar uma string equilibrada como entrada e saída dessa string virada do avesso. Nos casos em que pode haver várias saídas válidas, você precisa apenas produzir uma delas. Você pode usar um tipo de chave diferente ( <>
, []
ou {}
) se desejar.
Como é uma competição de código-golfe , você deve minimizar o tamanho do seu código-fonte, medido por bytes.
Casos de teste
(()()) -> ()(()), (())()
(()(())()) -> (()(())())
((())())() -> (()(()()))
fonte
Respostas:
Haskell ,
12412011911711311010910610510410198 bytes4 bytes salvos graças ao bartavelle!
3 bytes salvos graças ao Zgarb
1 byte salvo graças a Peter Taylor
Aqui está uma solução que eu trabalhei em Haskell. Está
tudo bem no momento,muito bom, graças a alguma ajuda que recebi, mas estou procurando diminuir isso, para que comentários / sugestões sejam apreciados.Experimente online!
Explicação
Este programa define 4 funções, a primeira
(!)
determina se uma string é balanceada. É definido da seguinte forma:Essa verificação pressupõe que a entrada tenha um número igual de parênteses de abertura e fechamento, graças a uma sugestão de Peter Taylor.
O próximo
g
girará a corda uma vez.Então nós temos o
d
que simplesmente pega um parênteses e o espelhaFinalmente, temos a função com a qual estamos preocupados. Aqui, usamos uma representação sem ponto de
until(!0)g
composta commap d
, que mapeiad
a entrada e se aplicag
até que o resultado seja equilibrado. Este é o processo exato descrito na pergunta.fonte
g x@(a:b)|x!0=x|1>0=g$b++[a]
e remover as parênteses parad '('=')'
.d
causa um erro do compilador, acredite em mim, eu tentei. Mas a primeira sugestão é bem-vinda. Obrigado!!
, porque você não precisa lidar com casos em que a corda tem um número desigual de parênteses de abertura e fechamento, assim você pode trocar os dois primeiros casos e têm_!1=1<0
[]!_=0<1
until
para encurtarg
: TIOd
mapa'('
para(-1)
e qualquer outra coisa para1
, e então os dois casos mais longos!
podem ser combinados(i:a)!x=a!(x+i)
. A estrutura de nível superior precisa ser reformulada paramap d
entrar nauntil
condição, e eu tenho que correr para não ter tempo agora para descobrir quais combinadores são necessários para colar tudo isso.SOGL V0.12 ,
1211 bytesExperimente aqui!
Explicação:
Nota:
l{
pode ser substituído por ( por 10 bytes, mas, infelizmente, não é implementado.fonte
CJam (20 caracteres)
Demonstração online
ou para a mesma contagem de caracteres
Demonstração online
Dissecação
As duas versões têm um cabeçalho e rodapé comuns
Então, o bit no meio obviamente calcula até onde é necessário girar. Ambos usam avaliação e dependem de
(
ser o operador de decremento do CJam e de)
serem o operador de incremento.vs
fonte
JavaScript (ES6),
111105 bytes(Economizou 2 bytes graças a @CraigAyre, 2 bytes graças a @PeterTaylor, 2 bytes graças a @Shaggy.)
Ungolfed:
Casos de teste:
Mostrar snippet de código
fonte
Retina ,
4638 bytesExperimente online! O link inclui casos de teste. Editar: salvou 8 bytes com a ajuda de @MartinEnder. O primeiro estágio simplesmente transpõe os parênteses, enquanto o segundo estágio procura o sufixo mais longo, que é um prefixo balanceado válido, o que aparentemente é uma condição suficiente para que a rotação seja totalmente balanceada. O balanceamento é detectado usando grupos de balanceamento. A construção
((\()|(?<-4>\)))+
corresponde a qualquer número de(
s mais qualquer número de)
s, desde que já tenhamos<-4>
visto ( ) tantos(
s. Como procuramos apenas um prefixo válido, não precisamos corresponder ao restante)
s .fonte
((\()|(?<-2>\)))
. Mas sua tentativa apenas me inspirou a encontrar uma abordagem completamente nova que economiza mais dois:(?<-1>(\()*\))+
. Isso certamente será útil no futuro, então obrigado. :)(?<-1>(\()*\))+
funciona, já que parece querer sair da1
pilha antes de realmente corresponder a qualquer coisa ...\(*
embora.PHP,
110108 bytesExecutar como tubo com
-nR
ou teste-o online .demolir
fonte
Python 3 ,
112103101 bytes-2 bytes graças a @ Mr.Xcoder
Experimente online!
fonte
Oitava, 62 bytes
Experimente online!
Uma função que recebe a string como entrada e imprime todos os resultados.
Explicação:
fonte
Mathematica, 78 bytes
fonte
JavaScript (ES6), 97 bytes
Funciona girando recursivamente a sequência de entrada até que sua transposição seja equilibrada e depois a transponha.
fonte
APL (Dyalog Unicode) ,
3530 bytesGolfou uma nova abordagem graças a @ Adám
Experimente online!
O golfe está em andamento.
Explicação
fonte
Python 2 , 99 bytes
Experimente online!
Em formato de função para casos de teste fáceis:
Python 2 , 108 bytes
Experimente online!
Isso usa uma abordagem um pouco diferente - em vez de girar recursivamente a string, se considerarmos os parênteses como incrementando e diminuindo algum contador de balança, uma string balanceada nunca deve ter uma soma total de incrementos - decrementos menores que 0.
Então pegamos
inverter as parênteses:
e converta-o em uma lista de somas de incrementos / decrementos:
-3 é o mínimo no índice 4 (baseado em zero); então queremos mudar por esse índice + 1. Isso garante que o incremento / decremento acumulado nunca será menor que 0; e será somado a 0.
fonte
r=0,
vez der=[0]
?r+=[r[-1]+2*b-1]
comr+=r[-1]+2*b-1,
bemClojure, 118 bytes
Retorna uma sequência de caracteres, então eu chamaria assim:
Primeiro vira colchetes e depois faz um loop enquanto a soma acumulada da contagem de colchetes for negativa em algum ponto da sequência.
fonte
brainfuck , 82 bytes
Experimente online!
Explicação
Com cada caractere lido, um contador é modificado da seguinte maneira:
)
, o contador aumenta em 1.(
, o contador diminui em 1, a menos que o contador seja 0; nesse caso, o contador permanece inalterado.Cada prefixo é um sufixo válido de uma string balanceada (após inversão) se e somente se esse contador for 0. Esse código usa o prefixo mais longo para formar a saída.
fonte