Regex, Papel, Tijeras, Lagarto, Spock

81

Calentamiento: expresiones regulares, papel, tijeras

Este es el desafío que originalmente quería publicar, antes de darme cuenta de que existe una solución muy corta. Sin embargo, puede ser un problema interesante para pensar en preparación para el desafío real a continuación.

Escribe tres expresiones regulares R , P y S de modo que coincidan entre sí en forma cíclica de piedra, papel y tijera. En particular, R coincide con S , S coincide con P y P coincide R , pero R no coincida con P , S no coincide con R y P no coincide con S . Aquí hay una tabla práctica:

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

No importa lo que R , P y S hagan en otras entradas, incluidos ellos mismos.

Aquí, la coincidencia solo significa que una subcadena (posiblemente vacía) de la entrada coincide. La coincidencia no necesita cubrir toda la entrada.

El desafío: expresiones regulares, papel, tijeras, lagarto, Spock

Para este desafío, resolverá una versión más difícil del problema anterior, basada en la variante RPS Rock, Paper, Scissors, Lizard, Spock (popularizada por The Big Bang Theory ). En RPSLV, hay cinco símbolos diferentes, que se superan en dos ciclos:

  • Piedra → Tijeras → Lagarto → Papel → Spock → Piedra
  • Roca → Lagarto → Spock → Tijeras → Papel → Roca

Debería escribir cinco expresiones regulares R , P , S , L y V que imitan esta estructura cuando se dan entre sí como entrada. Aquí está la tabla correspondiente:

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

Para que quede claro, usted debe no coincidir con la cadena R, Petc, pero las otras expresiones regulares. Por ejemplo, si su expresión regular R es, ^\w$por ejemplo, P y V tienen que coincidir con la cadena ^\w$, mientras que S y L no deberían.

Una vez más, la coincidencia solo significa que al menos una subcadena (posiblemente vacía) de la entrada coincide. La coincidencia no necesita cubrir toda la entrada. Por ejemplo \b(límite de palabra) coincide hello(al principio y al final), pero no coincide (^,^).

Puede usar cualquier sabor regex, pero indique la elección en su respuesta y, si es posible, proporcione un enlace a un probador en línea para el sabor elegido. No puede utilizar ninguna función de expresiones regulares que le permita invocar código en el idioma del host del sabor (como el emodificador del sabor Perl ).

Los delimitadores (como /regex/) no se incluyen en la expresión regular cuando se proporcionan como entrada a otra persona, y no puede usar modificadores que estén fuera de la expresión regular. Algunos sabores aún le permiten usar modificadores con sintaxis en línea como (?s).

Su puntaje es la suma de las longitudes de las cinco expresiones regulares en bytes. Más bajo es mejor.

Resulta mucho más sencillo encontrar una solución funcional a este problema de lo que parece al principio, pero espero que encontrar una solución óptima sea bastante complicado.

Martin Ender
fuente
¿Tiene, por ejemplo, que R debe coincidir con la expresión regular completa de S o una subcadena de S, siempre que no coincida con ninguna subcadena de P o V?
Okx
La coincidencia @Okx "solo significa que al menos una subcadena (posiblemente vacía) de la entrada coincide. La coincidencia no necesita cubrir toda la entrada. Por ejemplo, \bcoincidencias hello( límite de palabras) (al principio y al final), pero no coincide (^,^)".
Martin Ender
1
Presumiblemente no importa si una expresión regular coincide con sí misma?
Brilliand
@Brilliand Correcto.
Martin Ender
1
Gran rompecabezas He creado una versión interactiva aquí, si alguien está interesado: shark.fish/rock-paper-scissors
shark.dp

Respuestas:

45

PCRE .NET, 35 32 bytes

-3 bytes gracias a Martin Ender

Rock:

([*?]$)

Papel:

[)$]$+

Tijeras:

[+?]$.*

Lagartija:

[+$]$.?

Spock

[*)]$

La idea aquí es hacer coincidir los caracteres al final de otras expresiones regulares que son caracteres de expresiones regulares reservadas, pero dejar de ser tratados como tales dentro de una clase de caracteres.

Gato de negocios
fuente
1
Bien, tú ganas: P
ETHproductions
3
Uso disimulado de poner cosas después del EOL "$" que se ignoran cuando se usan activamente y se pueden combinar cuando se usan pasivamente
Stilez
44

PCRE, 15 14 bytes

Rock:
B

Papel:
\b$

Tijeras:
b|B.

Lagartija:
\B.

Spock
^\w

Anders Kaseorg
fuente
44
Muy impresionante.
Eric Duminil
¡Imbatible! He estado jugando con Rock = Q(existe una solución 14b con Lizard = `\ Q \`, luego el resto es similar al tuyo) pero fue en vano.
jaytea
40

sin características sofisticadas, 35 30 bytes

5 bytes guardados por la idea de Neil que utiliza que ]no necesita \.

Esto funciona, por ejemplo, con el remódulo python .

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

Busca un ]precedido por una letra que indica qué regla es.

Versión anterior utilizada, R='\[[RSL]'etc.

Un intento anterior con la puntuación 40 estaba usando R='[SL]x|Rx'etc.

Christian Sievers
fuente
1
Ahorre 5 bytes invirtiendo todo: R='[LSR]]'etc.
Neil
@Neil Esa es una gran mejora, ¡gracias!
Christian Sievers
This works with python's rebueno, Python probablemente debería ser el encabezado entonces
gato
1
@cat También escribí "por ejemplo", toda la oración es solo para decir algo concreto que realmente intenté. Supongo que podría decir POSIX como lo hicieron otros, pero creo que mi encabezado es bastante correcto.
Christian Sievers
26

PCRE, 20 19

Rock

W

Papel

^\w

tijeras

^\W

Spock

w?\x57$

Lagartija

[w]W?
TwiNight
fuente
21

20 bytes

R = 'R|VP'
L = 'L|RS'
V = 'V|LP'
S = 'S|RV'
P = 'P|LS'
emulbreh
fuente
¡Vaya, puede ser tan fácil!
Christian Sievers
Eso es hermoso.
Eric Duminil
8

JavaScript, 45 bytes

Otra solución trivial.

R:
^R|^.[SL]
P:
^P|^.[RV]
S:
^S|^.[PL]
L:
^L|^.[PV]
V:
^V|^.[SR]
dzaima
fuente
Oh, acabo de darme cuenta de que mi respuesta es una versión más larga / similar de la tuya, ¿quieres que la elimine?
TheLethalCoder
44
@TheLethalCoder Todas las respuestas actualmente son solo versiones más largas / más cortas una de la otra: p
dzaima
1
Supongo jaja ...
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?

Podría hacerse más corto, pero se usó el truco (ocultar coincidencias después de $), así que estoy buscando otra forma

Los primeros 5 caracteres de cada cadena se ignoran cuando coinciden. Entonces la cadena objetivo efectiva se simplifica a solo X? Y ?. Ninguno de ellos tiene letras dobles porque "?" es un carácter ordinario, por lo que los últimos 4 caracteres cuando se usan como expresiones regulares tienen que coincidir (cadena nula). Por lo tanto, los patrones colapsan a "contiene 5 caracteres seguidos de la letra de destino": lo que significa que los caracteres 6-9 del objetivo deben contener la letra de destino (el quinto carácter en cada cadena)

Actualización: versión de 35 bytes a continuación, ¡ahora!

Stilez
fuente
Siempre pensé que la V no es realmente para V ulcan, sino para representar la forma del saludo Vulcan (que es el gesto de la mano que usas para representar a Spock cuando juegas RPSLV en persona).
Martin Ender
De todos modos, ¡bienvenido a PPCG! Buena primera respuesta. Me gusta que haya invertido la lógica en comparación con todas las respuestas existentes (haciendo coincidir solo una letra y colocando las letras que superan la expresión regular actual en la expresión regular).
Martin Ender
¿POSIX ancla automáticamente la coincidencia al comienzo de la cadena? De lo contrario, ¿no podrías dejar esas comas?
Martin Ender
Creo que es POSIX. Podría ser perc. Pero sí, muy bien visto! ¡5 caracteres menos!
Stilez
44
No hay necesidad de competir con Jelly. Simplemente elige un idioma que te guste y diviértete. :)
Martin Ender
3

PCRE, 65 bytes

Esta es una solución realmente trivial, y no muy inteligente, pero trataré de jugarlo.

V:

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

L:

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

S:

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

PAGS:

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

R:

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

Esencialmente, cada expresión regular tiene un 'identificador', en forma de comentario, que le dice a las otras expresiones regulares si deben coincidir o no.

Okx
fuente
3

.NET, 50 bytes

En orden lo son R, P, S, L, V.

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

Funciona buscando el grupo identificador (por ejemplo, [^R]) en cada una de las otras expresiones.

Cambiar las expresiones a ^R|\^[SL], o similar, parece funcionar, pero es un poco demasiado similar a la respuesta de @ dzaima, aunque llegaría a 45 bytes.

TheLethalCoder
fuente
3

Vanilla RE, 40 caracteres

¡No es la solución más concisa o elegante, pero tiene una estructura visual cuasi-semántica agradable!

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

La piedra vence a las tijeras o al lagarto El
papel vence a Vulcano o la
piedra La tijera vence a Lagarto o al papel
Lagarto vence al papel o al vulcan
Vulcano vence a la piedra o la tijera

Chris D'Amato
fuente
2

POSIX, 35 bytes

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

Una forma completamente diferente de "esconderse" detrás de un símbolo de inicio / fin, así que me siento bien al respecto :) Estoy haciendo coincidir para comenzar porque "?" siempre tendría que ir entre letra y final / $ si se realiza de la otra manera.

10 bytes menos que mi primera solución, y conceptualmente simple, que es una ventaja que me gusta.

Stilez
fuente