¿Qué consejos generales tienes para jugar al golf en Retina ? Estoy buscando ideas que puedan aplicarse a los problemas de golf de código en general que sean al menos algo específicos de Retina (por ejemplo, "eliminar comentarios" no es una respuesta). Por favor, publique un consejo por respuesta.
Como referencia, el compilador en línea está aquí .
@ Sp3000 señaló que también hay consejos para Regex Golf . Las respuestas aquí deberían centrarse específicamente en las características de Retina y no en consejos generales de golf regex.
Respuestas:
Combina bucles si es posible
En los cálculos no triviales, a menudo se encontrará utilizando varios bucles para procesar datos:
Entonces esto funciona
stage1
hasta que la salida converge, luegostage2
hasta que la salida converge y luegostage3
hasta que converge la salida.Sin embargo, siempre vale la pena examinar las etapas en detalle. A veces es posible ejecutar el bucle de una manera intercalada
stage1, stage2, stage3, stage1, stage2, stage3, ...
(esto depende mucho de lo que realmente hacen las etapas, pero a veces hacen cambios completamente ortogonales o funcionan bien como una tubería). En este caso, puede guardar bytes envolviéndolos en un solo bucle:Si
stage1
es la primera etapa ostage3
es la última etapa del programa, incluso puede omitir uno de esos paréntesis (lo que significa que esto ya puede guardar bytes para un ciclo de dos etapas).Un uso reciente de esta técnica se puede ver en esta respuesta .
fuente
División de cuerdas en trozos de igual longitud
n
Como en la mayoría de los idiomas "normales" TMTOWTDI (hay más de una forma de hacerlo). Asumo aquí que la entrada no contiene saltos de línea, y que "dividir" significa dividirla en líneas. Pero hay dos objetivos muy diferentes: si la longitud de la cadena no es un múltiplo de la longitud del fragmento, ¿desea mantener el fragmento final incompleto o desea descartarlo?
Mantener un trozo final incompleto
En general, hay tres formas de dividirse en Retina. Aquí presento los tres enfoques, porque pueden hacer una gran diferencia cuando intentas adaptarlos a un problema relacionado. Puede usar un reemplazo y agregar un salto de línea a cada coincidencia:
Eso es 8 bytes (o un poco menos si
n = 2
on = 3
porque entonces puedes usar..
o...
respectivamente). Sin embargo, esto tiene un problema: agrega un salto de línea adicional si la longitud de la cadena es un múltiplo de la longitud del fragmento.También puede usar una etapa dividida y aprovechar el hecho de que las capturas se retienen en la división:
La
_
opción elimina las líneas vacías que de lo contrario resultarían de cubrir toda la cadena con coincidencias. Esto es 9 bytes, pero no agrega un salto de línea final. Porn = 3
sus 8 bytes y porn = 2
sus 7 bytes. Tenga en cuenta que puede guardar un byte en general si las líneas vacías no importan (por ejemplo, porque de todos modos solo procesará líneas no vacías y eliminará los avances de línea): entonces puede eliminar el_
.La tercera opción es usar una coincidencia. Con la
!
opción podemos imprimir todos los partidos. Sin embargo, para incluir el fragmento final, debemos permitir una longitud de coincidencia variable:Esto también es de 9 bytes, y tampoco incluirá un salto de línea final. Esto también se convierte en 8 bytes para
n = 3
hacerlo..?.?
. Sin embargo, tenga en cuenta que se reduce a 6 bytesn = 2
porque ahora solo necesitamos..?
. También tenga en cuenta queM
puede eliminarse si esta es la última etapa de su programa, guardando un byte en cualquier caso.Descartando un trozo final incompleto
Esto se vuelve realmente largo si intentas hacerlo con un reemplazo, porque necesitas reemplazar el fragmento final con nada (si existe) y también con una división. Entonces podemos ignorarlos con seguridad. Curiosamente, para el enfoque de partido es lo contrario: se acorta:
Eso es 7 bytes, o menos de
n = 2
,n = 3
. Nuevamente, tenga en cuenta que puede omitirM
si esta es la última etapa del código.Si desea un avance de línea final aquí, puede obtenerlo agregando
|$
la expresión regular.Bonus: trozos superpuestos
Recuerde que
M
tiene la&
opción que devuelve coincidencias superpuestas (que normalmente no es posible con expresiones regulares). Esto le permite obtener todos los fragmentos superpuestos (subcadenas) de una cadena de una longitud determinada:fuente
123456
convierte123\n456
y se1234567890
convierte12345\n67890
??=
.