Regex, papier, ciseaux, lézard, spock

81

Échauffement: regex, papier, ciseaux

C’est le défi que j’ai voulu publier à l’origine, avant de réaliser qu’il existe une solution très courte. Néanmoins, il peut être intéressant de réfléchir à la préparation du défi ci-dessous.

Ecrivez trois regex R , P et S de telle sorte qu’ils se correspondent dans un style cyclique Rock, Paper, Scissors. En particulier, R correspond S , S correspond à P et P correspond à R , mais R ne correspond P , S ne correspond R et P ne correspond pas à S . Voici un tableau pratique:

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

Peu importe ce que font R , P et S sur d’autres entrées, y compris elles-mêmes.

Ici, correspondance signifie simplement que certaines sous-chaînes (éventuellement vides) de l'entrée sont mises en correspondance. La correspondance n'a pas besoin de couvrir la totalité de l'entrée.

Le défi: regex, papier, ciseaux, lézard, spock

Pour ce défi, vous résolvez une version plus sévère du problème ci-dessus, basée sur la variante RPS Rock, Paper, Scissors, Lézard, Spock (popularisée par The Big Bang Theory ). Dans RPSLV, il y a cinq symboles différents qui se battent en deux cycles:

  • Rock → Ciseaux → Lézard → Papier → Spock → Rock
  • Rock → Lézard → Spock → Ciseaux → Papier → Rock

Vous devriez écrire cinq expressions rationnelles R , P , S , L et V qui imitent cette structure lorsqu'elles sont données en entrée. Voici le tableau correspondant:

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

Pour être clair, vous devriez ne pas correspondre à la chaîne R, Petc, mais les autres expressions rationnelles. Par exemple, si votre expression rationnelle R est ^\w$par exemple, alors P et V doivent correspondre à la chaîne ^\w$, alors que S et L ne le devraient pas.

De nouveau, la correspondance signifie simplement qu'au moins une sous-chaîne (éventuellement vide) de l'entrée est mise en correspondance. La correspondance n'a pas besoin de couvrir la totalité de l'entrée. Par exemple \b(limite de mot) correspond hello(au début et à la fin), mais ne correspond pas (^,^).

Vous pouvez utiliser n’importe quelle saveur regex, mais veuillez indiquer votre choix dans votre réponse et, si possible, fournissez un lien vers un testeur en ligne pour la saveur choisie. Vous ne pouvez utiliser aucune fonctionnalité regex permettant d'appeler du code dans le langage hôte de la version (comme le emodificateur de la version de Perl ).

Les délimiteurs (comme /regex/) ne sont pas inclus dans la regex lorsqu'ils sont donnés en entrée à un autre, et vous ne pouvez pas utiliser de modificateurs en dehors de la regex. Certaines variantes vous permettent encore d'utiliser des modificateurs avec une syntaxe en ligne telle que (?s).

Votre score est la somme des longueurs des cinq regex en octets. Plus c'est bas, mieux c'est.

Il s'avère beaucoup plus simple de trouver une solution efficace à ce problème que cela ne semble à première vue, mais j'espère que trouver une solution optimale est assez délicat.

Martin Ender
la source
Par exemple, R doit-il correspondre à la regex entière de S ou à une sous-chaîne de S, à condition que cela ne corresponde à aucune sous-chaîne de P ou de V?
Okx
@Okx "match signifie simplement qu'au moins une sous-chaîne (éventuellement vide) de l'entrée est mise en correspondance. La correspondance ne doit pas nécessairement couvrir la totalité de l'entrée. Par exemple \b(limite de mot), les correspondances hello(au début et à la fin), mais ça ne correspond pas (^,^). "
Martin Ender
1
Vraisemblablement, peu importe si une regex correspond à elle-même?
Brilliand
@Brilliand Correct.
Martin Ender
1
Grand puzzle. J'ai créé une version interactive ici, si cela vous intéresse: shark.fish/rock-paper-scissors
shark.dp

Réponses:

45

PCRE .NET, 35 32 octets

-3 octets grâce à Martin Ender

Roche:

([*?]$)

Papier:

[)$]$+

Les ciseaux:

[+?]$.*

Lézard:

[+$]$.?

Spock:

[*)]$

L'idée ici est de faire correspondre les caractères à la fin des autres expressions rationnelles qui sont des caractères réservés aux expressions rationnelles, mais cessent d'être traitées comme telles à l'intérieur d'une classe de caractères.

Chat d'affaires
la source
1
Bon, vous gagnez: P
ETHproductions
3
Utilisation sournoise de placer des éléments après l'EOL "$" qui deviennent ignorés lorsqu'ils sont utilisés activement et qui
peuvent être couplés s'ils sont
44

PCRE, 15 14 octets

Roche:
B

Papier:
\b$

Les ciseaux:
b|B.

Lézard:
\B.

Spock:
^\w

Anders Kaseorg
la source
4
Très impressionnant.
Eric Duminil
Imbattable! Je bricole Rock = Q(une solution 14b existe avec Lizard = `\ Q \`, le reste est semblable au vôtre), mais en vain.
Jaytea
40

pas de fonctions de fantaisie, 35 30 octets

5 octets sauvés par l'idée de Neil qui utilise ce qui a ]besoin de pas \.

Cela fonctionne par exemple avec le remodule python .

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

Il recherche un ]précédé d'une lettre qui indique de quelle règle il s'agit.

Version précédente utilisée R='\[[RSL]'etc.

Une tentative antérieure avec le score 40 utilisait R='[SL]x|Rx'etc.

Christian Sievers
la source
1
Économisez 5 octets en inversant tout: R='[LSR]]'etc.
Neil
@ Neil C'est une grande amélioration, merci!
Christian Sievers
This works with python's reEh bien, Python devrait probablement être l'en-tête
cat
1
@cat J'ai aussi écrit "par exemple", toute la phrase est juste pour dire quelque chose de concret que j'ai réellement essayé. Je suppose que je pourrais dire POSIX comme d'autres, mais je pense que mon en-tête est tout à fait correct.
Christian Sievers
26

PCRE, 20 19

Roche

W

Papier

^\w

Les ciseaux

^\W

Spock

w?\x57$

Lézard

[w]W?
TwiNight
la source
21

20 octets

R = 'R|VP'
L = 'L|RS'
V = 'V|LP'
S = 'S|RV'
P = 'P|LS'
Emulbreh
la source
Oh wow, ça peut être si facile!
Christian Sievers
C'est beau.
Eric Duminil
8

JavaScript, 45 octets

Une autre solution triviale.

R:
^R|^.[SL]
P:
^P|^.[RV]
S:
^S|^.[PL]
L:
^L|^.[PV]
V:
^V|^.[SR]
dzaima
la source
Oh, je viens de réaliser que ma réponse est une version plus longue / similaire de la vôtre, tu veux que je la supprime?
TheLethalCoder
4
@TheLethalCoder Toutes les réponses sont actuellement juste des versions plus longues / plus courtes les unes des autres: p
dzaima
1
Je suppose haha ​​...
TheLethalCoder
5

POSIX, 50 45 octets

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

Pourrait être plus court mais le tour (masquer les correspondances après $) s’est utilisé, alors je cherche un autre moyen

Les 5 premiers caractères de chaque chaîne sont ignorés lors de la correspondance. Ainsi, la chaîne cible effective se simplifie pour ne comprendre que X? Y ?. Aucun d'entre eux n'a de lettres doubles parce que "?" est un caractère ordinaire, donc les 4 derniers caractères utilisés comme regex doivent correspondre (chaîne nulle). Ainsi, les modèles se réduisent à "contient 5 caractères suivis de la lettre cible": les caractères 6-9 de la cible doivent contenir la lettre cible (le 5ème caractère de chaque chaîne).

Mise à jour: version de 35 octets ci-dessous, maintenant!

Stilez
la source
J'ai toujours pensé que le V n'était pas vraiment pour V ulcan mais pour représenter la forme du salut Vulcan (qui est le geste de la main que vous utilisez pour représenter Spock lorsque vous jouez en RPSLV en personne).
Martin Ender
Quoi qu'il en soit, bienvenue à PPCG! Belle première réponse. J'aime le fait que vous ayez inversé la logique par rapport à toutes les réponses existantes (faire correspondre une seule lettre et mettre les lettres qui battent la regex courante dans la regex).
Martin Ender
POSIX ancre-t-il automatiquement la correspondance au début de la chaîne? Sinon, vous ne pouvez pas laisser tomber ces virgules?
Martin Ender
Je pense que c'est POSIX. Pourrait être perc. Mais oui, bien repéré! 5 caractères de moins!
Stilez
4
Il n'y a pas besoin de rivaliser avec Jelly. Il suffit de choisir une langue que vous aimez et amusez-vous. :)
Martin Ender
3

PCRE, 65 octets

C'est une solution vraiment triviale - et pas très intelligente du tout - mais je vais essayer de jouer au golf.

V:

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

L:

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

S:

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

P:

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

R:

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

Chaque regex a essentiellement un "identifiant", sous la forme d'un commentaire, qui indique aux autres regex si elles doivent être mises en correspondance ou non.

Okx
la source
3

.NET, 50 octets

Dans l'ordre ils sont R, P, S, L, V.

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

Fonctionne en recherchant le groupe d'identifiants (par exemple, [^R]) dans chacune des autres expressions.

Changer les expressions en ^R|\^[SL], ou similaire, semble fonctionner, mais ensuite, cela ressemble un peu trop à la réponse de @ dzaima, bien qu'elle atteigne 45 octets.

TheLethalCoder
la source
3

Vanilla RE, 40 caractères

Pas la solution la plus concise ou élégante, mais une structure visuelle quasi sémantique agréable!

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

Battements de roche Ciseaux ou Lézard
battements de papier Vulcan ou
Ciseaux de roche bat Lézard ou
Lézards de papier bat papier ou Vulcain
Vulcain bat de roche ou Ciseaux

Chris D'Amato
la source
2

POSIX, 35 octets

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

Une façon complètement différente de "se cacher" derrière un symbole de début / fin, donc je me sens bien à ce sujet :) Je m'apparente pour commencer parce que "?" devrait toujours aller entre letter et end / $ si on le faisait dans l’autre sens.

10 octets de moins que ma 1ère solution, et conceptuellement simple, ce qui est un bonus que j'aime bien.

Stilez
la source