Consejos para jugar al golf en Röda


12

Röda es un lenguaje de secuencias de comandos basado en secuencias creado por fergusq .

¿Qué consejos generales tienes para jugar al golf en Röda? Estoy buscando ideas que puedan aplicarse a problemas de código de golf y que también sean al menos algo específicas de Röda (por ejemplo, "eliminar comentarios" no es una respuesta).

Por favor, publique un consejo por respuesta.


¿Estás tratando de obtener consejos para vencerme en el golf? : P (probablemente debería mirar los consejos para la página de Python)
HyperNeutrino

¡Guau, una pregunta de PCG.SE que entró en las Preguntas de la Red Caliente y no es un desafío / rompecabezas de programación! :)
Pedro A

1
@HyperNeutrino Shhh .... :)
usuario41805

Respuestas:


7

Usa guiones bajos

Este es probablemente el consejo más importante. Casi todos los programas de golf de Röda utilizan guiones bajos.

La sintaxis de subrayado es el azúcar sintáctico para los forbucles. Las siguientes líneas de código son equivalentes:

ls""|fileLength x for x|sort|pull
ls""|fileLength _|sort|pull

Cada guión bajo agrega una nueva variable a un forbucle invisible que está alrededor de la declaración. El bucle extrae un valor de la secuencia para cada variable / guión bajo y luego se repite, hasta que no quedan valores.

Los guiones bajos se pueden usar en cualquier parte de las declaraciones:

a[x:y+1]=[1]*(1+y-x) /* Sets range x..y (inclusive) */
seq x,y|a[_]=1       /* 6 bytes less */

Si debe hacer referencia al mismo valor de subrayado más de una vez, o utilizar los valores en orden inverso, puede poner un número después del subrayado:

a|[_^_1]  /* maps x to x^x */
a|[_2-_1] /* maps each pair (x,y) to y-x, eg. [1,2,4,8] -> [1, 4] */

3

Algunos puntos y comas son opcionales

Al escribir el código Röda, generalmente se recomienda usar líneas nuevas o punto y coma para separar todas las declaraciones. Sin embargo, al jugar al golf, vale la pena saber que no todos los puntos y comas son realmente necesarios.

Aquí hay una lista incompleta de lugares donde los puntos y comas son opcionales . La mayoría de ellos no se aplican cuando la siguiente declaración comienza con un operador ( (, [, +, etc.).

  • Después de las tareas
  • Después de las llamadas a funciones, cuando hay al menos un argumento (p. Ej. f x) O cuando se usan paréntesis (p. Ej. f())
  • En todas partes, si la línea siguiente / declaración comenzaría con |, ), ]o}

Si la siguiente instrucción comienza con un operador, el punto y coma / nueva línea es opcional si

  • La declaración es una llamada de función y se utilizan paréntesis, por ejemplo, {f(x)[y]}es igual que {f(x);[y]}. Esto funciona solo en el contexto de la instrucción, no cuando la llamada a la función es una expresión.
  • La declaración es una asignación y se utilizan paréntesis, por ejemplo, x=(y)[z]es igual que x=(y);[z](eso no es lo mismo que x=((y)[z])).

Y aquí hay algunos lugares donde desafortunadamente se requieren las nuevas líneas :

  • Después ++y --.
  • Después [...].

A menudo es posible guardar bytes reorganizando las asignaciones. Por ejemplo:

a=0;b=""c=[""]
b=""c=[b]a=0

x=f()y=i;z=a[0]
x=f()z=a[0]y=i

1

Usar estructuras de control de sufijo

Casi nunca es óptimo no usar sentencias de sufijo, como puede usar {...}en lugar de do...end.

Algunos ejemplos:

x|unless[not(_ in y)]do[0]else[1]done
x|[0]unless[not(_ in y)]else[1]

if[p<0]do c+=p;a-=p done
{c+=p;a-=p}if[p<0]

¿Puedes hacer en su if[_ in y]lugar?
user41805

@ KritixiLithos No, porque quiero que la condición sea OR, no AND. Actualmente verifica si hay al menos un valor xque también está en y, pero su condición verificará si todos los valores xtambién están en y. (El ejemplo se copió desde aquí ).
fergusq

1

Use la secuencia para la entrada

En los casos en que la entrada es una lista de elementos, puede ser beneficioso extraer los valores de la secuencia en lugar de obtenerlos como una matriz.

En la mayoría de los casos, los elementos de la matriz se iteran empujándolos a la secuencia y luego iterando con un forbucle (o un guión bajo). Como los elementos se repiten de la secuencia de todos modos, ¿por qué no definir que deberían estar allí desde el principio?

Por ejemplo, para calcular la suma de los cuadrados de los números en la entrada:

{|a|a|[_^2]|sum} /* Removing a redundant argument */
{[_^2]|sum}      /* saves 5 bytes */

1

Los paréntesis son opcionales en el contexto de la declaración. Esto se aplica incluso si el argumento comienza con un operador. Por ejemplo, [a()|sqrt-_]es más corto que [a()|sqrt(-_)]. Los paréntesis después ason obligatorios, como aen el contexto de la expresión, no en el contexto de la declaración.

Sin embargo, la escritura [a()|sqrt(_+1)*2]no es posible, y se necesitan paréntesis adicionales para ayudar a que el analizador: [a()|sqrt((_+1)*2)]. A menudo es posible reescribir tal expresión para que no comience con un paréntesis:[a()|sqrt 2*(_+1)]


¿También es posible pasar múltiples parámetros a funciones sin requerir paréntesis?
user41805

@KritixiLithos Sí. P.ej. [a()|atan2 _,_]Sería permitido.
fergusq

1

Usar en ,lugar de ..en []/ pushdeclaraciones

Relacionado: Usar en ,lugar deand

La pushfunción (así como la printfunción) puede tomar cualquier número de argumentos y genera cada uno de ellos sin delimitador.

Eso significa algo como esto

["a"..b]        /*8 bytes (string "a" concatenated with variable b)*/

puede acortarse en solo

["a",b]         /*7 bytes*/

ahorrando 1 byte.


1

[]/ push>print

Nunca use printdeclaraciones. []las declaraciones push son siempre más golfistas. La diferencia entre printy pushes que el primero genera una nueva línea final mientras que el segundo no. Sin embargo, esto se puede evitar.

print"a"              /* 8 bytes */
["a                   /* 6 bytes; uses a literal newline */
"]

print"a",b            /* 10 bytes */
[`a$b                 /* 8 bytes; uses a literal newline and `` strings */
`]

1

Usando ``cadenas

En ""cadenas, tendrás que escapar de ciertos personajes para poder usarlos. Por ejemplo, para imprimir la barra diagonal inversa, tendría que tener una cadena como "\\". Hay un byte agregado para escapar de la barra invertida. Sin embargo, si lo usa ``, no tiene que escapar de este personaje y puede guardar un byte.

print"\\"     /* 9 bytes */
print`\`      /* 8 bytes */

No solo eso, puede codificar variables y expresiones dentro de ``cadenas usando $variableNameo ${expression}, una característica que no está presente en las ""cadenas.

Estamos generando la cadena "a"concatenada con el valor de la variable bcon una nueva línea final en estos ejemplos.

["a",b,"      /* 11
"]               bytes   */
[`a$b         /* 8
`]               bytes; encodes b in the string using $b */

1

Usar en ,lugar deand

Las condiciones en Röda son flujos y pueden constar de múltiples valores. Estos valores se reducen a un valor booleano con and.

Esto significa que puede reemplazar andcon ,en condiciones para enviar múltiples valores a la secuencia:

x if[a and b]
x if[a,b]

La condición vacía es verdadera

También es posible tener una condición que no contiene valores, lo cual es cierto.

x while true
x while[]

1

Escribir listas de reemplazo en forma *"...;..."/";"

La replacefunción toma normalmente una lista de cadenas como argumentos. Sin embargo, si la lista es muy larga, es beneficioso simplemente almacenar los pares regex / reemplazo en una cadena y luego dividir la cadena y usar el operador estrella:

replace"a","b","c","d"
replace*"a;b;c;d"/";"
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.