Seu desafio é criar uma regex que corresponda a todas as permutações de string em si e nada mais. A correspondência também deve fazer distinção entre maiúsculas e minúsculas.
Então, por exemplo, se o seu regex for:
ABC
Ele deve corresponder (e corresponder apenas) às seguintes strings:
ABC
ACB
BAC
BCA
CAB
CBA
Não deve corresponder a coisas como:
AABC (contains an extra A)
ABCD (contains an extra D)
AC (no B)
AAA (no B and C, extra 2 A's)
abc (case-sensitive)
Regras:
- Você tem permissão para usar qualquer sabor de regex que desejar.
- Aplicam-se brechas padrão.
- Você deve ter pelo menos dois caracteres diferentes no seu código. Isso significa que soluções como
1
são inválidas. - O regex deve conter apenas ASCII imprimível e nada mais.
(ABC|ACB|BAC|BCA|CAB|CBA)
mas você queria uma resposta generalizada.Respostas:
JavaScript,
6457 bytes4 bytes removidos graças a Martin Ender.
Experimente aqui.
Explicações (desatualizadas)
fonte
^(?!.*(\S)(.*\1){3}[^1]?)[]zzSS[-^?!!.'''-*1{33}0066-]{60}\z
regex101^(?'4'(?!(.*\4){3})[]$$[\\^^?!!..'-*{}33-5-]){54}$[5]*
Regex Perl e PCRE, 280 bytes
(Um pouco) mais legível:
Isso é executado no tempo O (2 ^ n) conforme escrito, e é incrivelmente ineficiente. A maneira mais fácil de testá-lo é substituir todas as ocorrências de
.*
por.*?
, o que faz com que o caso em que corresponde seja verificado primeiro (o que significa que corresponde em tempo linear, mas ainda leva tempo exponencial se não corresponder).A idéia básica é que aplicamos o comprimento do regex igual a 280 e usamos asserções lookahead para forçar cada caractere no regex a aparecer pelo menos um certo número de vezes, por exemplo,
(?=(.*z){2})
força oz
caractere a aparecer pelo menos duas vezes.2+43+43+22+23+2+6+16+7+4+1+3+2+2+1+22+22+11+2+23+23
é 280, então não podemos ter ocorrências "extras" de nenhum caractere.Este é um exemplo de programação de um autograma , uma frase que se descreve listando o número de cada caractere que ele contém (e, nesse caso, também o comprimento total). Tive muita sorte em construí-lo (normalmente você precisa usar força bruta, mas me deparei com essa solução enquanto testava meu programa de força bruta antes de terminar de escrevê-lo).
Regex Perl e PCRE, 253 bytes, em colaboração com Martin Ender
Minha hipótese era de que poderia haver soluções mais curtas que omitem alguns dígitos (provavelmente 9, 8 ou 7). Martin Ender encontrou um, mostrado abaixo:
Versão legível:
fonte
{}
nas duas últimas viseiras. Você também não precisa adicionar coisas como,(?=(.*5){1})
pois não haveria um5
se você não tivesse essa aparência. Um problema é que$
permite um avanço de linha à direita, então você precisará usá\z
-lo em vez de$
como o jimmy fez, mas isso não custará um byte, acho que desde que você salvou o\
na primeira olhada.$
permitir uma nova linha no final da string, isso geralmente depende de como o regex é chamado pela região circundante. programa (normalmente são executados em código que já foi analisado em linhas).(?=(.*5){1})
neste caso. Se eu o removesse, haveria um 5 no programa, porque a(?=(.*1){6})
linha agora precisaria ler(?=(.*1){5})
.$
para\z
não causa nenhum dano (e não quebre o autograma).\$
...$
az
...\z
. Isso funciona; Eu vou mudar isso.