O problema
Eu tenho várias expressões regulares que preciso usar em algum código, mas estou usando uma linguagem de programação que não suporta regex! Felizmente, eu sei que a sequência de teste terá um comprimento máximo e será composta apenas por ASCII imprimível.
O desafio
É necessário introduzir uma expressão regular e um número n
, e saída de cada cadeia de caracteres composta por ASCII imprimível (códigos ASCII de 32 a 126, inclusive, para
~
, sem separadores ou novas linhas) de comprimento inferior ou igual a n
que corresponda a esse expressão regular. Você não pode usar expressões regulares incorporadas ou funções de correspondência de expressões regulares em seu código. Expressões regulares serão limitadas ao seguinte:
- Caracteres literais (e escapes, que forçam um caractere a ser literal, assim
\.
é um literal.
,\n
é um literaln
(equivalente a apenasn
) e\w
são equivalentes aw
. Você não precisa oferecer suporte a seqüências de escape.) .
- curinga (qualquer caractere)- Classes de caracteres,
[abc]
significa "a ou b ou c" e[d-f]
significam algo de d a f (então, d ou e ou f). Os únicos personagens que têm significado especial em uma classe de personagem são[
e]
(que sempre serão escapados, portanto, não se preocupe com eles),\
(o caractere de escape, é claro),^
no início da classe de personagem (que é uma negação ) e-
(que é um intervalo). |
- o operador OR, alternação.foo|bar
significa umfoo
oubar
, e(ab|cd)e
corresponde a umabe
oucde
.*
- corresponda ao token anterior repetido zero ou mais vezes, ganancioso (tenta repetir o máximo de vezes possível)+
- repetido uma ou mais vezes, ganancioso?
- zero ou uma vez- Agrupamento com parênteses, para os tokens de grupo para
|
,*
.+
ou?
A regex entrada será sempre válido (ou seja, você não tem que lidar com entrada, como ?abc
ou (foo
ou qualquer entrada inválida). Você pode produzir as strings na ordem que desejar, mas cada string deve aparecer apenas uma vez (não produza duplicatas).
Os casos de teste
Entrada: .*
, 1
saída: (string vazia), ,
!
, "
, ..., }
,~
Entrada: w\w+
, 3
saída: ww
,www
Entrada: [abx-z][^ -}][\\]
, 3
saída: a~\
, b~\
, x~\
, y~\
,z~\
Entrada: ab*a|c[de]*
, 3
saída: c
, cd
, ce
, aa
, cde
, ced
, cdd
, cee
,aba
Entrada: (foo)+(bar)?!?
, 6
saída: foo
, foo!
, foofoo
,foobar
Entrada: (a+|b*c)d
, 4
saída: ad
, cd
, aad
, bcd
, aaad
,bbcd
Entrada: p+cg
, 4
saída: pcg
,ppcg
Entrada: a{3}
, 4
saída:a{3}
O vencedor
Isso é código-golfe , então o código mais curto em bytes vencerá!
fonte
|
faz muito pouco sentido. Parece não manipular grupos aninhados oua|b|c
. O que há de errado em usar as explicações padrão em termos de quão fortemente concatenação e alternância se ligam? (E você não tem desculpa para não usar a caixa de areia)Respostas:
Haskell
757 705 700 692 679667resultado:
Explicação: esta é uma implementação de regex de livros didáticos. R é o tipo de expressão regular, com os construtores A (alternativo), L (literal), T (então) e E (vazio / epsilon). A 'Estrela' usual não aparece porque eu a inline alternadamente durante a análise (consulte '%'). 'm' executa a simulação. O analisador (inicie em 'rs = ....') é apenas descida recursiva; 'k' analisa intervalos. A função '#' expande intervalos em alternações.
fonte
Python v2.7
10691036950925897884871833822Essa resposta parece bastante longa para um código de golfe, mas há muitos operadores que precisam ser manipulados e eu sei qual é o objetivo de cada byte nesta resposta. Como não há resposta, eu a envio como um alvo para outros usuários vencerem. Veja se você pode fazer uma resposta mais curta :).
As duas funções principais são:
f
analisa o regex começando noi
th caractere ed
gera as seqüências correspondentes, usandor
os sub-regexes em que podemos recursar, 'a' a matriz que representa a parte do sub-regex atual ainda não processada, e um sufixo de sequências
que representa a parte da sequência gerada até agora.Verifique também a saída da amostra e um chicote de teste .
Observe que as guias na solução original foram
expand
editadas. Contar o número de caracteres no uso originalunexpand < regex.py | wc
.fonte
def E(a,b):c=a[:];c.extend(b);return c
paraE=lambda a,b:a[:].extend(b)
, idem paraA
elif isinstance(e,str):
, eu acredito que você poderia alterar o código interno para:exec{'.':'for c in C:d(r,p,s+chr(c))','?':'d(r,p,s);d(r,p[:z],s)','*':'''c=p[:z]#newline for i in R(0,n+1):d(r,c,s);c+=[p[z]]''','+':"d(r,p+['*',p[z]],s)",'\\':'d(r,p,e[1]+s)'}.get(e,'d(r,p,e+s)')
(observe que#newline
é uma nova linha) (fonte: stackoverflow.com/a/103081/1896169 ) #