Uma sequência de chaves é definida como uma sequência que consiste nos caracteres *()[]
nos quais as chaves correspondem corretamente:
[brace-string] ::= [unit] || [unit] [brace-string]
[unit] ::= "" || "*" || "(" [brace-string] ")" || "[" [brace-string] "]"
Esta é uma cadeia de chaves válida:
((())***[]**)****[(())*]*
Mas estes não são:
)(
**(**[*](**)
**([*)]**
Sua tarefa é escrever um programa (ou função) que, dado um número inteiro positivo n
, aceite um número como entrada e produza (ou retorne) todas as cadeias de comprimento válidas n
.
Especificações
- Você pode imprimir as strings em qualquer ordem.
- Você pode produzir como uma lista ou uma sequência separada por um caractere diferente.
- Seu programa deve manipular 0 corretamente. Existe uma possível string de comprimento 0, que é a string vazia
""
. - Isso é código-golfe , então a resposta mais curta e válida - medida em bytes - vence.
Casos de teste
0.
1. *
2. ** () []
3. *** ()* []* (*) [*] *() *[]
4. **** ()** []** (*)* [*]* (**) **() **[] *(*) *[*] (()) ()() ()[] ([]) [**] [()] [[]] []() [][] *()* *[]*
code-golf
balanced-string
Esolanging Fruit
fonte
fonte
Respostas:
Gelatina, 29 bytes
-3 bytes graças a @JonathanAllan
Por favor , avise-me se houver algum problema / bugs / erro ou bytes que eu possa derrubar!
Experimente online!
As soluções anteriores que eu tinha:
Explicação (Minha melhor tentativa de descrição):
fonte
“[(*)]”ṗµḟ”*œṣ⁾()Fœṣ⁾[]FµÐLÐḟ
)Prolog, 69 bytes
Uma das propriedades mais interessantes do Prolog é que, em muitos casos, ele é capaz de executar um programa para trás; por exemplo, em vez de testar para ver se algo é verdadeiro, você pode gerar todas as soluções verdadeiras e, em vez de verificar o comprimento de uma string, pode gerar todas as strings com um determinado comprimento. (Outra propriedade interessante do Prolog é que ela requer espaço em branco após o final de cada definição de predicado, e uma nova linha pode ser inserida tão barata quanto um espaço; assim, mesmo os programas de golfe geralmente são legíveis.)
O item acima define um predicado (o equivalente a uma função)
b
que testa para verificar se uma string tem um determinado comprimento e é uma "string entre chaves", conforme definido na pergunta. Especificamente, isso é feito através do suporte de gramática / regex / correspondência de padrões do Prolog, que fornece um pouco de açúcar agradável para definir esse tipo de expressão (aparentemente isso é padrão / portátil, mas eu não sabia disso enquanto escrevia a resposta originalmente e, portanto, assumimos que a resposta funcionaria apenas em uma implementação do Prolog; parece que funciona em todas as implementações que cumprem os padrões). O programa pode ser traduzido para o inglês diretamente; as duas primeiras linhas dizem "an s é uma string vazia, ou e seguido de an é um asterisco, ou entre parênteses, ou um s ; um e s seguido por um nulo " corda." s entre colchetes ". A terceira linha pode ser interpretada como" O b de N pode ser A se A for uma lista com comprimento N e A for um sTomei alguns cuidados para escrever
s
(e, portantob
), de modo que elas coincidam com cada "string cinta" em exatamente uma maneira (que é a razão que tantos
ee
tem que existir, em vez de agrupá-los em um predicado). Isso os torna totalmente reversíveis; portanto,b
pode ser usado para gerar todas as "strings" de um determinado comprimento, além de testar se uma string é uma string de um determinado comprimento (também pode ser usada uma terceira maneira, para descobrir o comprimento de uma cinta) , mas esse é quase certamente o seu modo de operação menos útil). A implementação é recursiva, por exemplo, para gerar um s , o código gerará todos os e s possíveis que não excedam o comprimento exigido da saída e anexará todos os s possíveiss que cabem no espaço restante a eles; como especifiquei antecipadamente o comprimento do argumento (em b ), o mecanismo do Prolog sabe que não pode gerar uma saída maior que o comprimento especificado, o que permite que a recursão seja encerrada.Aqui está um exemplo do programa em operação:
fonte
length
e deappend
qualquer maneira é uma parte fundamental da linguagem, e as funções do usuário geralmente fazem o mesmo.length(A,N)
; ifN
é dado eA
não é (o que acontecerá se o predicado for usado da maneira solicitada no programa),length
gerará uma listaA
composta porN
elementos desconhecidos. Usarlength
para medir o comprimento de uma lista é provavelmente mais comumente usado (embora usá-lo "para trás" seja bastante comum na programação do Prolog). A maioria dos predicados acaba funcionando da mesma maneira (a única razão pela qual eles não o fazem é se tentar revertê-los construiria um loop infinito, o que é bastante comum).-->
e DCGs em geral são o Prolog ISO padrão .Haskell,
10194 bytes7 bytes salvos pelo Zgarb!
Quase simples, seguindo a definição, mas com o
""
caso movido.Usar:
(O segundo cálculo leva menos de um segundo em uma máquina lenta.)
Eu também gostaria de compartilhar o resultado de outra abordagem que surgiu quando pensava em gerar funções. Ele define uma lista
b
de listas de seqüências de caracteres queb!!n
contêm todas as chaves de comprimenton
. Da mesma forma,u!!n
contém todos os átomos do tamanhon-1
. Uma coisa boa é que o código não está usando números. Não é completamente golfed:u
ei
poderia ser embutido, e certamente perde algumas outras oportunidades de golfe. Infelizmente, não parece que possa ser menor do que a primeira versão, mas calculalength $ b !! 10
ainda mais rápido.fonte
b$n-k
eb$n-2
. Além disso, na linha final, você pode fazera:b<-["()","[]"]
e retornara:s++b
.["()","[]"]
mas não conseguia ver como melhorar o tamanho do código. Obrigado!Mathematica, 116 bytes
Explicação
Encontre os caracteres da string
"*([)]"
, dando oList
{"*", "(", "[", ")", "]"}
.Encontre as tuplas da lista acima com o comprimento
n
.Função booleana sem nome para descobrir se a tupla está equilibrada:
Exclua tudo
"*"
na entrada.Exclua repetidamente todas as ocorrências consecutivas de
"("
e")"
ou"["
e"]"
até que a entrada não seja alterada.Verifique se o resultado está vazio
List
.Encontre as tuplas que são fornecidas
True
quando a função booleana é aplicada.Converta cada um
List
dos caracteres emString
s.fonte
{x=a___,"(",")",y=b___}|{x,"[","]",y}
parece funcionar.Python 2, 128 bytes
Dane-se as expressões regulares recursivas - estamos usando o analisador do Python! Para verificar se, por exemplo,
*(**[])*
é uma cadeia de chaves, fazemos o seguinte:Faça uma string como
"*", (0,"*","*", [0,0] ,0) ,"*"
, onde cada segundo caractere de quatro é um caractere das chaves, e os caracteres restantes são colados para tornar essa uma possível expressão em Python.eval
isto.Se isso não gerar um erro, imprima
s[1::4]
(os caracteres da cadeia de caracteres).Os caracteres de cola são escolhidos para que a string que eu crie seja uma expressão Python válida se, e somente se, tirar cada segundo caractere em cada quatro produzir uma string de chave válida.
fonte
PHP, 149 bytes
Usa o bom e velho método gerar todos os possíveis e, em seguida, filtrar. Use como:
fonte
Python, 134 bytes
repl.it
Função sem nome que retorna uma lista de cadeias de comprimento válidas
n
.Forma todas as
n
tuplas de comprimento dos caracteres*()[]
, une-as em seqüências de caracteres usandomap(''.join,...)
e filtros para aqueles que têm colchetes balanceados removendo os "pares""*"
e"()"
,"[]"
por suan
vez, e verificando se o resultado é uma sequência vazia (osn
tempos são um exagero, especialmente para"*"
mas é golfista).fonte
Retina , 78 bytes
A contagem de bytes assume a codificação ISO 8859-1.
Experimente online!
Explicação
Estou gerando todas as sequências possíveis de comprimento 5 e depois filtro as inválidas.
Isso converte a entrada em unário, usando
1
como dígito.Isso repetidamente (
+
) substitui o primeiro (1
) em cada linha (%
) de forma que ele faça cinco cópias da linha, uma para cada caractere possível. Isso é feito usando as substituições de prefixo e sufixo$`
e$'
para construir o restante de cada linha.Esse loop é interrompido quando não há mais 1s para substituir. Neste ponto, temos todas as seqüências de comprimento possíveis
N
, uma em cada linha.Esses dois estágios são executados para cada linha separadamente (
%
). O primeiro estágio simplesmente duplica a linha, com a;
para separar as duas cópias.O segundo estágio é outro loop (
+
), que remove repetidamente[]
,()
ou*
da primeira cópia da string, ou remove um ponto-e-vírgula no início da linha (que só é possível depois que a string desapareceu completamente).Seqüências de caracteres válidas são aquelas que não têm mais um ponto e vírgula na frente delas, então simplesmente descartamos todas as linhas (
A
) que contêm um ponto e vírgula.fonte
Python 3.5, 146 bytes
Muito longo em comparação com outras respostas, mas a mais curta que pude encontrar atualmente. Ele está na forma de uma função lambda anônima e, portanto, deve ser chamado no formato
print(<Function Name>(<Integer>))
Saídas um Python conjunto de unordered sequências representando todas as sequências de chaves possíveis do comprimento da entrada.
Por exemplo, supondo que a função acima seja nomeada
G
, a chamadaG(3)
resultaria na seguinte saída:Experimente Online! (Ideona)
No entanto, se, como eu, você não é realmente um fã de simplificar as coisas usando built-ins, então aqui é a minha própria originais resposta não usando qualquer bibliotecas externas para encontrar permutações, e atualmente em pé em um colossal
288237 bytes :Novamente, como a resposta da concorrência, esta está na forma de uma função lambda e, portanto, também deve ser chamada no formato
print(<Function Name>(<Integer>))
E gera uma lista Python de seqüências não ordenadas, representando todas as chaves do comprimento da entrada. Por exemplo, se o lambda fosse chamado como
G(3)
, desta vez a saída seria a seguinte:Além disso, este também é muito mais rápido que minha outra resposta, sendo capaz de encontrar todas as chaves de comprimento
11
em cerca de 115 segundos , as de duração10
em cerca de 19 segundos , as de duração9
em cerca de 4 segundos e as de duração8
em cerca de 0,73 segundos na minha máquina, enquanto minha resposta concorrente leva muito mais que 115 segundos para uma entrada de6
.Experimente Online! (Ideona)
fonte
05AB1E, 23 bytes
Alguns desses recursos podem ter sido implementados após a publicação da pergunta. Todas as sugestões são bem-vindas!
Experimente online!
Quão?
fonte
*
também estar na matriz de remoção? E oõQ
cheque poderia ser substituído por algo como NÃO?'*м„()„[]‚õ:
vs„()„[]‚'*«õ:
(não testado), pois não há comando para concatenar 3 valores AFAIK. O segundo não funcionará, pois não existe um NOT que funcionaria assim em uma string, o AFAIK. (Onde AFAIK representa "tanto quanto eu sei")