No popular (e essencial) livro de ciência da computação, Uma Introdução às Línguas Formais e Autômatos, de Peter Linz, a seguinte linguagem formal é freqüentemente declarada:
principalmente porque esse idioma não pode ser processado com autômatos de estado finito. Essa expressão significa "A linguagem L consiste em todas as cadeias de 'a's seguidas de' b's, nas quais o número de 'a's e' b's é igual e diferente de zero".
Desafio
Escreva um programa / função de trabalho que obtenha uma string, contendo apenas "a" se "b" s , como entrada e retorna / gera um valor verdade , dizendo se essa string é válida na linguagem formal L.
Seu programa não pode usar nenhuma ferramenta de computação externa, incluindo rede, programas externos, etc. Os shells são uma exceção a esta regra; O Bash, por exemplo, pode usar utilitários de linha de comando.
Seu programa deve retornar / produzir o resultado de uma maneira "lógica", por exemplo: retornando 10 em vez de 0, som de "bipe", saída para stdout etc. Mais informações aqui.
Aplicam-se regras de código padrão de golfe.
Este é um código de golfe . O menor código em bytes vence. Boa sorte!
Casos de teste de verdade
"ab"
"aabb"
"aaabbb"
"aaaabbbb"
"aaaaabbbbb"
"aaaaaabbbbbb"
Casos de teste de falsidade
""
"a"
"b"
"aa"
"ba"
"bb"
"aaa"
"aab"
"aba"
"abb"
"baa"
"bab"
"bba"
"bbb"
"aaaa"
"aaab"
"aaba"
"abaa"
"abab"
"abba"
"abbb"
"baaa"
"baab"
"baba"
"babb"
"bbaa"
"bbab"
"bbba"
"bbbb"
fonte
empty string == truthy
enon-empty string == falsy
seria aceitável?a^n b^n
ou similar, ao invés de apenas o número dea
s igualando o número deb
s)Respostas:
MATL ,
54 bytesImprime uma matriz não vazia de 1 s se a string pertencer a L e uma matriz vazia ou uma matriz com 0 s (ambos falsificados) caso contrário.
Obrigado a @LuisMendo por jogar fora um byte!
Experimente online!
Como funciona
fonte
Python 3, 32 bytes
Saídas via código de saída : Erro para false, nenhum erro para True.
A cadeia é avaliada como código Python, substituindo parênteses
(
pora
e)
parab
. Somente expressões do formulárioa^n b^n
se tornam expressões bem formadas de parênteses((()))
, avaliando a tupla()
.Qualquer parêntese incompatível gera um erro, assim como vários grupos
(()())
, pois não há separador. A cadeia vazia também falha (seria bem-sucedidaexec
).A conversão
( -> a
,) -> b
é feita usandostr.translate
, que substitui os caracteres, tal como indicado por uma cadeia que serve como uma tabela de conversão. Dada a sequência de 100 comprimentos ") (" * 50, as tabelas mapeiam os primeiros 100 valores ASCII comoque leva
( -> a
,) -> b
. No Python 2, as conversões para todos os 256 valores ASCII devem ser fornecidas, exigindo"ab"*128
um byte a mais; obrigado a isaacg por apontar isso.fonte
*128
faz?128
pode ser substituído por50
(ou,99
nesse caso) para salvar um byte.Retina , 12 bytes
Créditos para FryAmTheEggman que encontrou esta solução de forma independente.
Imprime
1
para entrada válida ou0
não.Experimente online! (A primeira linha ativa um conjunto de testes separado por avanço de linha.)
Explicação
Grupos de balanceamento exigem sintaxe cara, então estou tentando reduzir uma entrada válida para um formulário simples.
Estágio 1
O
+
instrui o Retina a repetir esse estágio em um loop até que a saída pare de mudar. Ele corresponde aab
oua;b
e o substitui por;
. Vamos considerar alguns casos:a
s eb
s na cadeia não são equilibradas, da mesma forma que(
e)
normalmente precisa ser, algunsa
oub
permanecerá na cadeia, uma vez queba
, oub;a
não pode ser resolvido e um únicoa
oub
por si só não pode ou. Para se livrar de todos osa
s eb
s tem que haver uma correspondenteb
ao direito de cadaa
.a
eb
não são todos aninhados (por exemplo, se temos algo comoabab
ouaabaabbb
), então vamos acabar com múltiplos;
(e, potencialmente, algunsa
s eb
s), porque a primeira iteração vai encontrar váriosab
s para inseri-los e mais iterações preservará o número de;
na sequência.Portanto, se e somente se a entrada for do formato , acabaremos com um único na string.
anbn
;
Etapa 2:
Verifique se a sequência resultante contém apenas um ponto e vírgula. (Quando digo "marcar", na verdade, quero dizer ", conte o número de correspondências da regex especificada, mas como essa regex pode corresponder no máximo uma vez devido às âncoras, isso fornece um
0
ou outro1
.)fonte
Haskell, 31 bytes
A compreensão da lista
[c|c<-"ab",'a'<-s]
faz uma corda de uma'a'
para cada'a'
, ems
, seguido por um'b'
para cada'a'
nos
. Evita a contagem correspondendo a uma constante e produzindo uma saída para cada correspondência.Essa sequência é verificada como igual à sequência original e a sequência original é verificada como não vazia.
fonte
f=g.span id.map(=='a');g(a,b)=or a&&b==(not<$>a)
). Bem feito.Grime , 12 bytes
Experimente online!
Explicação
A primeira linha define um não terminal
A
, que corresponde a uma letraa
, possivelmente o não terminalA
, e depois uma letrab
. A segunda linha corresponde à entrada inteira (e
) contra o não-terminalA
.Versão não competitiva de 8 bytes
Depois de escrever a primeira versão desta resposta, atualizei o Grime para considerar
_
como o nome da expressão de nível superior. Esta solução é equivalente à acima, mas evita repetir o rótuloA
.fonte
Braquilog ,
2319 bytesExperimente online!
Explicação
fonte
05AB1E , 9 bytes
Código:
Explicação:
Os últimos dois bytes podem ser descartados se for garantido que a entrada não está vazia.
Usa a codificação CP-1252 . Experimente online! .
fonte
.M{J¹ÔQ0r
pelo seu.Gelatina , 6 bytes
Imprime a própria string se ela pertence a L ou está vazia e 0, caso contrário.
Experimente online! ou verifique todos os casos de teste .
Como funciona
Versão alternativa, 4 bytes (não concorrente)
Imprime 1 ou 0 . Experimente online! ou verifique todos os casos de teste .
Como funciona
fonte
J, 17 bytes
Isso funciona corretamente para fornecer falsey para a string vazia. Erro é falsey.
Versões antigas:
Prova e explicação
O verbo principal é uma bifurcação que consiste nestes três verbos:
Isso significa, "O menor de (
<.
) o comprimento (#
) e o resultado do dente direito ((-:'ab'#~-:@#)
)".O dente direito é um trem de 4 trens , composto por:
Vamos
k
representar nossa entrada. Então, isso é equivalente a:-:
é o operador de partida, portanto, os principais-:
testes de invariância sob o garfo monádico'ab' #~ -:@#
.Como o dente esquerdo do garfo é um verbo, ele se torna uma função constante. Portanto, o garfo é equivalente a:
O dente direito do garfo reduz pela metade (
-:
) o comprimento (#
) dek
. Observe#
:Agora, isso é
k
apenas com entradas válidas, então terminamos aqui.#
erros para strings de comprimento ímpar, que nunca satisfazem o idioma, então também estamos prontos.Combinada com o menor do comprimento e isso, a cadeia vazia, que não faz parte da nossa linguagem, produz seu comprimento
0
, e terminamos com tudo.fonte
2&#-:'ab'#~#
que você evitasse o erro e apenas saísse0
usando 12 bytes.Bison / YACC 60 (ou 29) bytes
(Bem, a compilação para um programa YACC é composta por algumas etapas, portanto, você pode incluir algumas para isso. Veja abaixo os detalhes.)
A função deve ser bastante óbvia se você souber interpretá-la em termos de gramática formal. O analisador aceita um
ab
ou uma
seguido por qualquer sequência aceitável seguida por ab
.Essa implementação depende de um compilador que aceita a semântica de K&R para perder alguns caracteres.
É mais elaborado do que gostaria com a necessidade de definir
yylex
e chamargetchar
.Ajuntar com
(a maioria das opções para o gcc é específica para o meu sistema e não deve contar na contagem de bytes; convém contar o
-std=c89
que adiciona 8 ao valor listado).Correr com
ou equivalente.
O valor de verdade é retornado ao sistema operacional e os erros também são relatados
syntax error
na linha de comandos. Se eu puder contar apenas a parte do código que define a função de análise (que é negligenciar o segundo%%
e tudo o que se segue), recebo uma contagem de 29 bytes.fonte
Perl 5.10,
3517 bytes (com sinalizador -n )Garante que a sequência inicie com
a
s e depois retorne emb
s. Corresponde apenas se os dois comprimentos forem iguais.Agradeço a Martin Ender por reduzir pela metade a contagem de bytes e me ensinar um pouco sobre a recursão nas expressões regulares: D
Retorna a string inteira, se corresponder, e nada, se não.
Experimente aqui!
fonte
$_&&=y/a//==y/b//
(requer-p
), sem o vazio, você pode soltar o valor&&
por 16! Tão perto ...echo -n 'aaabbb'|perl -pe '$_+=y/a//==y/b//'
mas não posso mudar outro byte ... Talvez precise desistir disso!JavaScript,
545544Constrói uma regex simples com base no comprimento da string e a testa. Para uma string de comprimento 4 (
aabb
), a regex se parece com:^a{2}b{2}$
Retorna um valor de verdade ou falsey.
11 bytes salvos graças a Neil.
fonte
f=
pode ser omitido.s=>s.match(`^a{${s.length/2}}b+$`)
?C,
5753 bytesSolução antiga de 57 bytes de comprimento:
Compilado com gcc v. 4.8.2 @Ubuntu
Obrigado ugoren pelas dicas!
Experimente no Ideone!
fonte
(t+=2)
parat++++
para -1 byte.t++++
não é um código C válido.t+=*s%2*2
e:*s*!1[s]
Retina , 22 bytes
Outra resposta mais curta no mesmo idioma acabou de chegar ...
Experimente online!
Esta é uma vitrine dos grupos de balanceamento na regex, explicada por Martin Ender .
Como minha explicação não chegaria nem perto da metade, vou apenas ligar para ela e não tentar explicar, pois isso seria prejudicial para a glória de sua explicação.
fonte
Befunge-93, 67 bytes
Experimente aqui! Pode explicar como funciona depois. Também pode tentar jogar um pouco mais, apenas por diversão.
fonte
MATL , 9 bytes
Experimente online!
A matriz de saída é verdadeira se não estiver vazia e todas as suas entradas forem diferentes de zero. Caso contrário, é falso. Aqui estão alguns exemplos .
fonte
código de máquina x86,
2927 bytesHexdump:
Código de montagem:
Repete os
a
bytes no começo e depois nos seguintes bytes 'b'. O primeiro loop aumenta um contador e o segundo diminui. Depois, faz um OR bit a bit entre as seguintes condições:b
s não for 0, a sequência também não corresponderáEntão, ele deve "inverter" o valor da verdade
eax
- configure-o para 0 se não for 0 e vice-versa. Acontece que o código mais curto para fazer isso é o seguinte código de 5 bytes, que eu roubei da saída do meu compilador C ++ pararesult = (result == 0)
:fonte
neg eax
definir o sinalizador de transporte como antes,cmc
inverter o sinalizador de transporte esalc
definir AL como FFh ou 0, dependendo de o sinalizador de transporte estar definido ou não. Economiza 2 bytes, apesar de ter um resultado de 8 bits em vez de 32 bits.xor eax,eax | xor ecx,ecx | l1: inc ecx | lodsb | cmp al, 'a' | jz l1 | dec esi | l2: lodsb | cmp al,'b' | loopz l2 | or eax,ecx | setz al | ret
Ruby, 24 bytes
(Essa é apenas a brilhante idéia de xnor na forma de Ruby. Minha outra resposta é uma solução que eu realmente criei.)
O programa pega a entrada, transforma
a
eb
para[
e]
respectivamente, e a avalia.A entrada válida formará uma matriz aninhada e nada acontece. Uma expressão desequilibrada fará com que o programa falhe. No Ruby, a entrada vazia é avaliada como
nil
, que trava porquenil
não definiu um*
método.fonte
Sed, 38 + 2 = 40 bytes
Uma saída de string não vazia é verdadeira
Autômatos de estados finitos não podem fazer isso, você diz? E os autômatos de estados finitos com loops . : P
Corra com
r
en
sinalizadores.Explicação
fonte
JavaScript,
4442O riscado 44 ainda é regular 44;
Funciona por forma recursiva tirando o exterior
a
eb
e recursivamente utilizando o valor interno seleccionado mas.+
. Quando não há correspondência à^a.+b$
esquerda, o resultado final é se a sequência restante é o valor exatoab
.Casos de teste:
fonte
ANTLR, 31 bytes
Usa o mesmo conceito que a resposta YACC do @ dmckee , apenas um pouco mais.
Para testar, siga as etapas no tutorial de introdução do ANTLR . Em seguida, coloque o código acima em um arquivo chamado
A.g4
e execute estes comandos:Em seguida, teste dando entrada no STDIN para
grun A r
:Se a entrada for válida, nada será produzido; se for inválido,
grun
dará um erro (outoken recognition error
,extraneous input
,mismatched input
ouno viable alternative
).Exemplo de uso:
fonte
grammer
palavra-chave é fedorenta para jogar golfe com o antlr. Meio como usar o fortran .C, 69 bytes
69 bytes:
#define f(s)strlen(s)==2*strcspn(s,"b")&strrchr(s,97)+1==strchr(s,98)
Para quem não conhece:
strlen
determina o comprimento da stringstrcspn
retorna o primeiro índice na string em que a outra string é encontradastrchr
retorna um ponteiro para a primeira ocorrência de um caracterestrrchr
retorna um ponteiro para a última ocorrência de um caractereUm grande obrigado a Titus!
fonte
>97
vez de==98
R,
646155 bytes,7367 bytes (robusto) ou 46 bytes (se cadeias vazias forem permitidas)Mais uma vez, a resposta do xnor retrabalhou. Se está implícito pelas regras que a entrada será composto de uma série de
a
s eb
s, ele deve funcionar: retorna NULL se a expressão é válida, lança e erro ou nada contrário.Se a entrada não for robusta e puder conter algum lixo, por exemplo
aa3bb
, a seguinte versão deverá ser considerada (deve retornarTRUE
para casos de teste verdadeiros, não NULL):Finalmente, se cadeias vazias forem permitidas, podemos ignorar a condição para entrada não vazia:
Novamente, NULL se for bem-sucedido, qualquer outra coisa.
fonte
NULL
), versão 2: apenas nada (entrada correta retorna somenteTRUE
), versão 3 (assumindo cadeias vazias são OK, como estado):NULL
. R é uma linguagem estatística orientada a objetos que tipifica tudo bem, sem nenhum aviso.if((y<-scan(,''))>'')eval(parse(t=chartr('ab','{}',y)))
Japonês , 11 bytes
Experimente online!
Dá um
true
ou outrofalse
, exceto o que""
dá""
que é falso em JS.Descompactado e como funciona
Adotado da solução MATL de Dennis .
fonte
C (Ansi),
6575 bytesGolfe:
Explicação:
Define um valor j e incrementa j em cada be diminui j em qualquer outra coisa. Verificado se a letra anterior é menor ou igual à próxima letra, para evitar que o abab funcione
Editar% s
Adicionadas verificações para casos abab.
fonte
ba
ouabab
?Lote, 133 bytes
Retorna um
ERRORLEVEL
de 0 em caso de sucesso, 1 em caso de falha. O lote não gosta de fazer a substituição de substring em cadeias vazias; portanto, precisamos verificar isso com antecedência; se um parâmetro vazio fosse legal, a linha 6 não seria necessária.fonte
PowerShell v2 +,
6152 bytesPega a entrada
$n
como uma string, cria$x
comohalf the length
. Constrói uma-and
comparação booleana entre$n
e um-match
operador de expressão regular contra a expressão regular de um número igual dea
'seb
'. Saídas booleanas$TRUE
ou$FALSE
. O$n-and
existe para explicar""
=$FALSE
.Alternativo, 35 bytes
Isso usa o regex da resposta do Leaky , com base nos grupos de balanceamento do .NET, apenas encapsulados no
-match
operador PowerShell . Retorna a string para truthy, ou string vazia para falsey.fonte
-match
contra$args[0]
, caso contrário,-match
irá funcionar como um filtro[0]
aqui porque recebemos apenas uma entrada e precisamos apenas de um valor truthy / falsey como saída. Como uma string vazia é falsey e uma string não vazia é verdadeira, podemos filtrar a matriz e recuperar a string de entrada ou nada, o que satisfaz os requisitos do desafio.Pitão - 13 bytes
Explicado:
fonte
&qS*/lQ2"ab
+4
será expandido para+4Q
(preenchimento implícito de argumentos) #Haskell, 39 bytes
Exemplo de uso:
p "aabb"
->True
.scanl(\s _->'a':s++"b")"ab"x
crie uma lista de todos["ab", "aabb", "aaabbb", ...]
com um total de(length x)
elementos.elem
verifica sex
está nesta lista.fonte
Python,
4340 bytesconsiderou a solução óbvia graças a Leaky Nun
outra ideia, 45 bytes:
-4 bytes usando len / 2 (eu recebo um erro quando chega a metade)
agora dá false para a string vazia
-3 bytes graças ao xnor
fonte
lambda s:list(s)==sorted("ab"*len(s)//2)
(Python 3)lambda s:s=="a"*len(s)//2+"b"*len(s)//2
(Python 3)''<
vez des and
descartar a caixa vazia.