Regex, Papel, Tesoura, Lagarto, Spock

81

Aquecimento: Regex, Papel, Tesoura

Esse é o desafio que eu originalmente queria postar, antes de perceber que existe uma solução muito curta. No entanto, pode ser um problema interessante de se pensar na preparação para o desafio real abaixo.

Escreva três expressões regulares R , P e S de forma que elas se combinem de uma maneira cíclica de Pedra, Papel e Tesoura. Em particular, R corresponde a S , S corresponde P e P corresponde ao R , mas R não coincidir com P , S não coincidir com R e P não coincide com S . Aqui está uma tabela útil:

Regex   Matches   Doesn't match
R       S         P
P       R         S
S       P         R

Não importa o que R , P e S façam em outras entradas, inclusive elas mesmas.

Aqui, match significa apenas que alguma substring (possivelmente vazia) da entrada é correspondida. A correspondência não precisa cobrir toda a entrada.

O desafio: Regex, Papel, Tesoura, Lagarto, Spock

Para esse desafio, você resolverá uma versão mais difícil do problema acima, com base na variante RPS Rock, Paper, Scissors, Lizard, Spock (conforme popularizado pela The Big Bang Theory ). No RPSLV, existem cinco símbolos diferentes, que se superam em dois ciclos:

  • Pedra → Tesoura → Lagarto → Papel → Spock → Pedra
  • Rocha → Lagarto → Spock → Tesoura → Papel → Rocha

Você deve escrever cinco regexes R , P , S , L e V que imitam essa estrutura quando dados um ao outro como entrada. Aqui está a tabela correspondente:

Regex   Matches   Doesn't match
R       L, S      V, P
L       V, P      S, R
V       S, R      P, L
S       P, L      R, V
P       R, V      L, S

Só para ficar claro, você deve não correspondem à cadeia R, P, etc, mas as outras expressões regulares. Por exemplo, se o seu regex R for, ^\w$por exemplo, P e V devem corresponder à string ^\w$, enquanto S e L não devem.

Novamente, match significa apenas que pelo menos uma substring (possivelmente vazia) da entrada é correspondida. A correspondência não precisa cobrir toda a entrada. Por exemplo \b(limite de palavras) corresponde hello(no início e no final), mas não corresponde (^,^).

Você pode usar qualquer sabor regex, mas indique a opção na sua resposta e, se possível, forneça um link para um testador on-line para o sabor escolhido. Você não pode usar nenhum recurso de regex que permita chamar código no idioma do host do sabor (como o emodificador do sabor Perl ).

Delimitadores (como /regex/) não são incluídos no regex quando fornecidos como entrada para outro e você não pode usar modificadores que estão fora do regex. Alguns tipos ainda permitem o uso de modificadores com sintaxe embutida (?s).

Sua pontuação é a soma dos comprimentos das cinco expressões regulares em bytes. Menor é melhor.

Parece muito mais simples encontrar uma solução funcional para esse problema do que pode parecer à primeira vista, mas espero que encontrar uma solução ótima seja bastante complicado.

Martin Ender
fonte
Digamos, R precisa corresponder a toda a regex de S ou a uma subcadeia de S, desde que não corresponda a nenhuma subcadeia de P ou V?
Okx 5/07
@Okx "corresponde apenas ao fato de que pelo menos uma substring (possivelmente vazia) da entrada é correspondida. A correspondência não precisa abranger toda a entrada. Por exemplo \b(limite de palavras) corresponde hello(no início e no final), mas não corresponde (^,^)".
Martin Ender
1
Presumivelmente, não importa se um regex corresponde a si mesmo?
Brilliand
@Brilliand Correct.
Martin Ender
1
Ótimo quebra-cabeça. Eu criei uma versão interativa aqui, se alguém estiver interessado: shark.fish/rock-paper-scissors
shark.dp

Respostas:

45

PCRE .NET, 35 32 bytes

-3 bytes graças a Martin Ender

Rocha:

([*?]$)

Papel:

[)$]$+

Tesouras:

[+?]$.*

Lagarto:

[+$]$.?

Spock:

[*)]$

A idéia aqui é combinar caracteres no final de outras regexes que são reservadas, mas deixar de ser tratado como tal quando estiver dentro de uma classe de caracteres.

Gato de negócios
fonte
1
Ok, você ganha: P
ETHproductions
3
Uso Sneaky de colocar as coisas após o "$" EOL que se tornam ignorado quando usado ativamente e matchable quando utilizado de forma passiva
Stilez
44

PCRE, 15 14 bytes

Rocha:
B

Papel:
\b$

Tesouras:
b|B.

Lagarto:
\B.

Spock:
^\w

Anders Kaseorg
fonte
4
Muito impressionante.
Eric Duminil
Imbatível! Eu tenho mexido com Rock = Q(existe uma solução 14b com Lizard = `\ Q \`, depois o restante é semelhante ao seu), mas sem sucesso.
Jaytea #
40

sem recursos sofisticados, 35 30 bytes

5 bytes salvos pela idéia de Neil, que usa o que ]não precisa \.

Isso funciona, por exemplo, com o remódulo python .

R='[SLR]]'
P='[RVP]]'
S='[PLS]]'
L='[PVL]]'
V='[SRV]]'

Ele procura um ]precedido por uma letra que indique qual é a regra.

Versão anterior usada R='\[[RSL]'etc.

Uma tentativa anterior com pontuação 40 estava usando R='[SL]x|Rx'etc.

Peneiradores cristãos
fonte
1
Salvar 5 bytes, invertendo tudo: R='[LSR]]'etc.
Neil
@ Neil Isso é uma grande melhoria, obrigado!
Christian Sievers
This works with python's rebem, Python provavelmente deve ser o cabeçalho, em seguida
gato
1
@cat Eu também escrevi "por exemplo", a frase toda é apenas para dizer algo concreto que eu realmente tentei. Acho que posso dizer POSIX como outros fizeram, mas acho que meu cabeçalho está correto.
Christian Sievers
26

PCRE, 20 19

Rocha

W

Papel

^\w

Tesouras

^\W

Spock

w?\x57$

Lagarto

[w]W?
TwiNight
fonte
21

20 bytes

R = 'R|VP'
L = 'L|RS'
V = 'V|LP'
S = 'S|RV'
P = 'P|LS'
emulbreh
fonte
Oh uau, pode ser tão fácil!
Christian Sievers
Isso é bonito.
Eric Duminil
8

JavaScript, 45 bytes

Outra solução trivial.

R:
^R|^.[SL]
P:
^P|^.[RV]
S:
^S|^.[PL]
L:
^L|^.[PV]
V:
^V|^.[SR]
dzaima
fonte
Ah, acabei de perceber que minha resposta é uma versão mais longa / semelhante da sua, quer que eu a exclua?
TheLethalCoder
4
@TheLethalCoder Todas as respostas atualmente são apenas versões mais longas / mais curtos de uns aos outros: p
dzaima
1
Suponho haha ...
TheLethalCoder
5

POSIX, 50 45 bytes

Rock
.{5}RP?V?
Paper
.{5}PS?L?
Scissors
.{5}SR?V?
Lizard
.{5}LR?S?
Vulcan (Spock)
.{5}VP?L?

Poderia ser feito mais curto, mas o truque (ocultar partidas depois de $) se acostumou, então estou procurando outra maneira

Os 5 primeiros caracteres de cada string são ignorados ao fazer a correspondência. Portanto, a cadeia de destino efetiva simplifica para apenas X? Y ?. Nenhum deles tem letras duplas porque "?" é um caractere comum, portanto, os quatro últimos caracteres quando usados ​​como regex precisam corresponder (sequência nula). Portanto, os padrões são reduzidos a "contém 5 caracteres seguidos pela letra de destino": o que significa que os caracteres de 6 a 9 do destino devem conter a letra de destino (o 5º de cada sequência)

Atualização: versão de 35 bytes abaixo, agora!

Stilez
fonte
Eu sempre pensei que o V não é realmente para o V ulcan, mas para representar a forma da saudação do Vulcan (que é o gesto com a mão que você usa para representar o Spock ao jogar RPSLV pessoalmente).
Martin Ender
De qualquer forma, bem-vindo ao PPCG! Ótima primeira resposta. Gosto que você inverteu a lógica em comparação com todas as respostas existentes (combinando apenas uma letra e colocando as letras que batem o regex atual no regex).
Martin Ender
O POSIX ancora automaticamente a correspondência no início da string? Caso contrário, você não poderia soltar essas vírgulas?
Martin Ender
Eu acho que é POSIX. Pode ser perc. Mas sim, bem localizado! 5 caracteres a menos!
Stilez 5/07
4
Não há necessidade de competir com Jelly. Basta escolher o idioma que você gosta e se divertir. :)
Martin Ender
3

PCRE, 65 bytes

Esta é uma solução realmente trivial - e não muito inteligente -, mas tentarei jogar com ela.

V:

(?#V).+[SR]\)

EU:

(?#L).+[PV]\)

S:

(?#S).+[PL]\)

P:

(?#P).+[RV]\)

R:

(?#R).+[SL]\)

Essencialmente, cada regex possui um 'identificador', na forma de um comentário, que informa aos outros regexes se deve ser correspondido ou não.

Okx
fonte
3

.NET, 50 bytes

Em ordem eles são R, P, S, L, V.

[^R]\^[SL]
[^P]\^[RV]
[^S]\^[PL]
[^L]\^[PV]
[^V]\^[SR]

Trabalha procurando o grupo identificador (por exemplo [^R]) em cada uma das outras expressões.

Alterar as expressões para ^R|\^[SL], ou similar, parece funcionar, mas é um pouco parecido com a resposta do @ dzaima, apesar de chegar a 45 bytes.

TheLethalCoder
fonte
3

Vanilla RE, 40 caracteres

Não é a solução mais concisa ou elegante, mas possui uma estrutura visual quase semântica agradável!

[^r][sl]
[^p][vr]
[^s][lp]
[^l][pv]
[^v][rs]

Pedra bate Tesoura ou Lagarto
Papel bate Vulcan ou Pedra
Tesoura bate Lagarto ou
Lagarto de papel bate Papel ou Vulcano
Vulcano bate Pedra ou Tesoura

Chris D'Amato
fonte
2

POSIX, 35 bytes

Rock
R?^[LS]
Paper
P?^[RV]
Scissors
S?^[LP]
Lizard
L?^[PV]
Vulcan (Spock)
V?^[RS]

Uma maneira completamente diferente de "esconder" atrás de um símbolo de início / fim, então eu me sinto bem com isso :) Estou combinando para começar porque "?" sempre teria que ir entre letra e final / $ se feito de outra maneira.

10 bytes a menos que a minha primeira solução e conceitualmente simples, que é um bônus que eu gosto.

Stilez
fonte