Consejos para jugar al golf en Retina

10

¿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.

Trauma digital
fuente
2
Relacionado: Consejos para regex golf
Sp3000
Hmmm, he estado retrasando la publicación de esto porque Retina todavía está en desarrollo y temía que la mayoría de las respuestas terminaran siendo simples consejos de golf regex, no muy específicos de Retina. Pero bien podríamos intentarlo, supongo ... :)
Martin Ender
@ MartinBüttner Usted y algunos otros me han dado muchos buenos consejos y sugerencias desde que comencé a mirar Retina, así que creo que probablemente sea hora de esto. Agregué una aclaración de que los consejos generales sobre expresiones regulares deberían ir a la pregunta vinculada.
Trauma digital
1
@ MartinBüttner Aquí hay un lugar tan bueno como cualquier otro para preguntar, me he estado preguntando por un tiempo, por curiosidad, ¿cuál es la inspiración para el nombre "Retina"? Supongo que la parte "Re" es para la expresión regular, pero ¿qué pasa con la "tina"?
Trauma digital
3
@ DigitalTrauma Estaba tratando de encontrar una buena palabra que funcionara como un acrónimo, pero fallé. La palabra "retina" estaba bastante cerca de algunos de los intentos, y me gustó la palabra. Sin embargo, nunca logré retomarlo en un acrónimo y desde entonces he renunciado a eso. Entonces sí, la "re" es una especie de "expresiones regulares" y tal vez la "n" para ".NET", pero en última instancia, es solo una palabra que sonaba bien.
Martin Ender

Respuestas:

3

Combina bucles si es posible

En los cálculos no triviales, a menudo se encontrará utilizando varios bucles para procesar datos:

+`stage1
+`stage2
+`stage3

Entonces esto funciona stage1hasta que la salida converge, luego stage2hasta que la salida converge y luego stage3hasta 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:

{`stage1
stage2
}`stage3

Si stage1es la primera etapa o stage3es 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 .

Martin Ender
fuente
2

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:

.{n}
$&¶

Eso es 8 bytes (o un poco menos si n = 2o n = 3porque 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:

S_`(.{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. Por n = 3sus 8 bytes y por n = 2sus 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:

M!`.{1,n}

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 = 3hacerlo ..?.?. Sin embargo, tenga en cuenta que se reduce a 6 bytes n = 2porque ahora solo necesitamos ..?. También tenga en cuenta que Mpuede 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:

M!`.{n}

Eso es 7 bytes, o menos de n = 2, n = 3. Nuevamente, tenga en cuenta que puede omitir Msi 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 Mtiene 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:

M!&`.{n}
Martin Ender
fuente
¿De alguna manera es posible dividir una cadena exactamente a la mitad con una longitud variable? Entonces se 123456convierte 123\n456y se 1234567890convierte 12345\n67890?
Kevin Cruijssen
1
@KevinCruijssen No creo que haya agregado ninguna característica específica para eso. Probablemente tendrá que usar grupos de equilibrio: tio.run / ##K0otycxLNPyvquGe8D / YIEHD3sZWQ09TW1PD3hbI1jW0A3JUNP//... Si no le importa un salto de línea final, puede omitir el ?=.
Martin Ender
Pude completar el desafío donde pensé que lo necesitaba de manera diferente, ¡pero los grupos de equilibrio son realmente muy útiles! Sabía que tenía que ser algo así, pero mis habilidades de expresión regular / retina no son lo suficientemente buenas. ¡Gracias por responder! :)
Kevin Cruijssen