Quels conseils généraux avez-vous pour jouer au golf à Retina ? Je cherche des idées qui peuvent être appliquées aux problèmes de golf de code en général qui sont au moins quelque peu spécifiques à Retina (par exemple, "supprimer les commentaires" n'est pas une réponse). Veuillez poster un pourboire par réponse.
Pour référence, le compilateur en ligne est ici .
@ Sp3000 a souligné qu'il existe également des conseils pour Regex Golf . Les réponses ici devraient se concentrer spécifiquement sur les fonctionnalités de la rétine et non sur les conseils généraux de golf regex.
Réponses:
Combinez les boucles si possible
Dans les calculs non triviaux, vous vous retrouverez souvent à utiliser plusieurs boucles pour traiter les données:
Donc, cela fonctionne
stage1
jusqu'à ce que la sortie converge, puisstage2
jusqu'à ce que la sortie converge, puisstage3
jusqu'à ce que la sortie converge.Cependant, cela vaut toujours la peine d'examiner les étapes en détail. Parfois, il est possible d'exécuter la boucle de manière entrelacée à la
stage1, stage2, stage3, stage1, stage2, stage3, ...
place (cela dépend beaucoup de ce que les étapes font réellement, mais parfois elles font des changements complètement orthogonaux ou fonctionnent bien comme un pipeline). Dans ce cas, vous pouvez enregistrer des octets en les enveloppant dans une seule boucle:Si
stage1
c'est la première étape oustage3
la dernière étape du programme, vous pouvez même omettre également l'une de ces parenthèses (ce qui signifie que cela peut déjà enregistrer des octets pour une boucle de deux étapes).Une utilisation récente de cette technique peut être vue dans cette réponse .
la source
Fractionnement de chaînes en morceaux de longueur égale
n
Comme dans la plupart des langues "normales" TMTOWTDI (il y a plus d'une façon de le faire). Je suppose ici que l'entrée ne contient pas de sauts de ligne, et que "fractionner" signifie la diviser en lignes. Mais il y a deux objectifs très différents: si la longueur de la chaîne n'est pas un multiple de la longueur du morceau, voulez-vous conserver le morceau de fin incomplet ou voulez-vous le supprimer?
Garder un morceau de fin incomplet
En général, il existe trois façons de procéder au fractionnement de la rétine. Je présente les trois approches ici, car elles pourraient faire une plus grande différence lorsque vous essayez de les adapter à un problème connexe. Vous pouvez utiliser un remplacement et ajouter un saut de ligne à chaque correspondance:
C'est 8 octets (ou un peu moins si
n = 2
oun = 3
parce qu'alors vous pouvez utiliser..
ou...
respectivement). Cependant, cela a un problème: il ajoute un saut de ligne supplémentaire si la longueur de la chaîne est un multiple de la longueur du bloc.Vous pouvez également utiliser une étape fractionnée et utiliser le fait que les captures sont conservées dans la division:
L'
_
option supprime les lignes vides qui résulteraient autrement de la couverture de la chaîne entière avec des correspondances. C'est 9 octets, mais cela n'ajoute pas de saut de ligne de fin. Pourn = 3
c'est 8 octets et pourn = 2
c'est 7 octets. Notez que vous pouvez enregistrer un octet dans l'ensemble si les lignes vides n'ont pas d'importance (par exemple parce que vous ne traiterez que les lignes non vides et vous débarrasserez des sauts de ligne de toute façon plus tard): alors vous pouvez supprimer le_
.La troisième option consiste à utiliser une correspondance. Avec l'
!
option, nous pouvons imprimer tous les matchs. Cependant, pour inclure le fragment de fin, nous devons autoriser une longueur de correspondance variable:Cela représente également 9 octets et n'inclura pas non plus de saut de ligne. Cela devient également 8 octets pour
n = 3
en faisant..?.?
. Notez cependant qu'il se réduit à 6 octetsn = 2
car maintenant nous n'en avons besoin que..?
. Notez également que leM
peut être supprimé s'il s'agit de la dernière étape de votre programme, en économisant un octet dans tous les cas.Jeter un fragment de fin incomplet
Cela devient vraiment long si vous essayez de le faire avec un remplacement, car vous devez remplacer le morceau de fin par rien (s'il existe) et également par un fractionnement. Nous pouvons donc les ignorer en toute sécurité. Fait intéressant, pour l'approche par match, c'est l'inverse: elle raccourcit:
C'est 7 octets, ou moins pour
n = 2
,n = 3
. Encore une fois, notez que vous pouvez omettre leM
si c'est la dernière étape du code.Si vous voulez un saut de ligne de fin ici, vous pouvez l'obtenir en l'ajoutant
|$
à l'expression régulière.Bonus: morceaux qui se chevauchent
N'oubliez pas que
M
l'&
option a pour résultat de renvoyer des correspondances qui se chevauchent (ce qui n'est normalement pas possible avec regex). Cela vous permet d'obtenir tous les morceaux (sous-chaînes) qui se chevauchent d'une chaîne d'une longueur donnée:la source
123456
devient123\n456
et1234567890
devient12345\n67890
??=
.