Je veux essayer un nouveau type de défi de golf regex, qui vous demande de résoudre des tâches de calcul non triviales avec rien de moins que la substitution de regex. Pour rendre cela plus possible et moins pénible, il vous sera permis d'appliquer plusieurs substitutions, l'une après l'autre.
Le défi
Commençons simplement: étant donné qu'une chaîne contenant deux entiers positifs, sous forme de nombres décimaux séparés par un ,
, produit une chaîne contenant leur somme, également sous la forme d'un nombre décimal. Donc, très simplement
47,987
devrait se transformer en
1034
Votre réponse devrait fonctionner pour des entiers positifs arbitraires.
Le format
Chaque réponse devrait être une séquence d'étapes de substitution, chaque étape consistant en une expression rationnelle et une chaîne de remplacement. Facultativement, pour chacune de ces étapes de la séquence, vous pouvez choisir de répéter la substitution jusqu'à ce que la chaîne cesse de changer. Voici un exemple de soumission (qui ne résout pas le problème ci-dessus):
Regex Modifiers Replacement Repeat?
\b(\d) g |$1 No
|\d <none> 1| Yes
\D g <empty> No
Compte tenu de l'entrée 123,456
, cette soumission traiterait l'entrée comme suit: la première substitution est appliquée une fois et donne:
|123,|456
Maintenant, la deuxième substitution est appliquée dans une boucle jusqu'à ce que la chaîne cesse de changer:
1|23,|456
11|3,|456
111|,|456
111|,1|56
111|,11|6
111|,111|
Et enfin, la troisième substitution est appliquée une fois:
111111
Notez que le critère de terminaison pour les boucles est de savoir si la chaîne a été modifiée, et non si l'expression régulière a trouvé une correspondance. (En d’autres termes, il est également possible qu’il se termine si vous trouvez une correspondance, mais le remplacement est identique à la correspondance.)
Notation
Votre score principal sera le nombre d'étapes de substitution dans votre soumission. Chaque substitution répétée comptera pour 10 étapes. Ainsi, l'exemple ci-dessus marquerait 1 + 10 + 1 = 12
.
Dans le cas d'égalité (pas très improbable), le score secondaire est la somme des tailles de toutes les étapes. Pour chaque étape, ajoutez l'expression régulière ( sans délimiteurs), les modificateurs et la chaîne de substitution. Pour l'exemple ci-dessus, ce serait(6 + 1 + 3) + (3 + 0 + 2) + (2 + 1 + 0) = 18
.
Règles diverses
Vous pouvez utiliser n’importe quel goût de regex (que vous devez indiquer), mais toutes les étapes doivent utiliser le même goût. De plus, vous ne devez utiliser aucune fonctionnalité du langage hôte de la version, comme les rappels de remplacement ou le e
modificateur de Perl , qui évalue le code Perl. Toute manipulation doit avoir lieu exclusivement par substitution de regex.
Notez que cela dépend de votre saveur et des modificateurs si chaque remplacement remplace toutes les occurrences ou si une seule. Par exemple, si vous choisissez la variante ECMAScript, une seule étape ne remplacera par défaut qu'une occurrence, à moins que vous n'utilisiez le g
modificateur. Par contre, si vous utilisez la version .NET, chaque étape remplacera toujours toutes les occurrences.
Pour les langues ayant différentes méthodes de substitution pour le remplacement unique et global (par exemple, Ruby's sub
vs. gsub
), supposons que le remplacement unique soit la valeur par défaut et traite le remplacement global comme un g
modificateur.
Essai
Si votre version choisie est .NET ou ECMAScript, vous pouvez utiliser Retina pour tester votre soumission (on me dit que cela fonctionne également sur Mono). Pour les autres variantes, vous devrez probablement écrire un petit programme dans le langage hôte qui applique les substitutions dans l’ordre. Si vous le faites, veuillez inclure ce programme de test dans votre réponse.
la source
Réponses:
Saveur .NET, score: 2
Je ne suis pas encore dérangé pour jouer au golf, et
x
c'est juste pour ignorer les espaces blancs.Il insère d’abord
9876543210
à chaque position, puis supprime les caractères originaux et ceux qui ne sont pas le chiffre actuel de la somme.Le grand regex (1346 octets sans espaces et commentaires):
Cela m'a fait penser au niveau final de Manufactoria ... Mais je pense que la regex .NET, qui n'est évidemment plus "régulière", peut résoudre tous les problèmes de PH. Et ceci est juste un algorithme dans L.
la source
Score: 24
Je pense que ça marche ...
Je n'ai pas encore passé beaucoup de temps à jouer au golf dans les expressions régulières. Je vais essayer de poster une explication bientôt, mais il se fait tard maintenant. En attendant, voici le résultat entre chaque étape:
Programme complet en Perl:
la source
Toute saveur regex, 41
Essayons unaire.
d
sert pour un séparateur d'ordre numérique,x
stocke la valeur. Tout d'abord, nous décomposons chaque chiffre, puis nous comprimons les multiplicateurs x10 à gauche, puis supprimons tous les séparateurs, puis réinsérons les multiplicateurs, puis convertissons chaque commande en chiffres.la source
.NET Regex, 14
Pas aussi bon que la solution de user23013, mais c'était amusant. Aucun des remplaçants ont modificateurs.
La raison de la regex .NET n’est pas due à l’équilibrage des groupes pour une fois - je viens de tester avec Retina , qui utilise .NET, et j'ai également constaté que la recherche de longueur variable aidait beaucoup.
Remplacement 1 (répéter = non)
Regex:
Remplacement
Échangez les deux nombres, le rembourrage ayant le même nombre de zéros au début.
Remplacement 2 (répétition = non)
Regex:
Remplacement:
Ajouter un espace avant chaque numéro
Remplacement 3 (répétition = non)
Remplacement:
Ajoutez un support (le
&0
) ainsi que la table de recherche géante de<c> <a> <b> <carry of a+b+c> <last digit of a+b+c>
.Remplacement 4 (répéter = oui)
Regex:
Remplacement:
Continuez à prendre les derniers chiffres de chaque numéro et trouvez leur (somme, report). Mettez la somme au début de la chaîne et remplacez le report.
Remplacement 5 (répétez = non)
Regex:
Remplacement:
Nettoyer.
Exemple d'exécution
(En combinant quelques-unes des étapes, je peux obtenir 12, mais comme cela devient assez compliqué et que je ne gagnerai pas de toute façon, je pense que je garderai cette version plus élégante à la place.)
la source
Score:
50403121Merci pour cet excellent challenge. Cette solution n'est pas très élégante, mais compte tenu des restrictions, je ne voyais aucun moyen de gérer un chiffre de manière générique dans la sortie.
Cette solution comporte des groupes de capture qui parfois ne correspondent pas et exige qu’ils soient vides le cas échéant. Cela fonctionne en Perl, bien qu'il génère normalement un avertissement.
Exemple complet de code Perl, avec explication et impression des résultats intermédiaires:
Mise à jour: J'ai été capable de combiner deux des expressions rationnelles en boucle ensemble, en économisant 10.
Mise à jour 2: J'ai réussi à déchiffrer la conversion des chiffres d'entrée avec une seule expression régulière.
Mise à jour 3: J'ai réduit à une seule expression rationnelle en boucle.
la source
${1}
différent de$1
? En outre, vous pouvez inclure le nombre d'octets en cas d'égalité.\1
, etc., en enregistrant quelques caractères.