Advertencia : Muro de texto acercándose. Son muchos pequeños trucos que reuní con el tiempo.
Escribe tus soluciones como bloques anónimos
Esto ya se mencionó pero me gustaría reiterarlo. En TIO, puede escribir my $f =
en el encabezado, el bloque en el código propiamente dicho, y comenzar el pie de página con un ;
. Esta parece ser, con mucho, la forma más corta de hacer el trabajo (ya que no necesita preocuparse por leer ninguna entrada, se le da en los argumentos).
Otra buena manera es usar el -n
o el -p
interruptor, pero no encontré una manera de hacerlo funcionar en TIO.
Use la sintaxis de dos puntos para pasar argumentos
Es decir, en lugar de thing.method(foo,bar)
, puedes hacer thing.method:foo,bar
y guardar 1 personaje. Desafortunadamente, no puede llamar a otro método en el resultado por razones obvias, por lo que tiene sentido usar solo el último método en un bloque.
Usa $_
todo lo que puedas
A veces es mejor tomar un solo argumento de lista que varios argumentos separados debido a esto. Al acceder $_
, puede llamar a los métodos simplemente comenzando con un punto: por ejemplo, .sort
es igual a $_.sort
.
Sin embargo, tenga en cuenta que cada bloque tiene el suyo propio $_
, por lo que los parámetros del bloque externo no se propagarán a los internos. Si necesita acceder a los parámetros de la función principal desde un bloque interno, ...
Usa las ^
variables si no puedes usar$_
Insertar una ^
entre el sello y el nombre de la variable, así: $^a
. Estos funcionan solo dentro de un bloque. El compilador primero cuenta cuántos de estos tiene en el bloque, los ordena lexicográficamente y luego asigna el primer argumento al primero, el segundo al segundo y así sucesivamente. Las ^
necesidades para ser utilizado sólo en la primera aparición de la variable. Entonces {$^a - $^b}
toma 2 escalares y los resta. Lo único que importa es el orden alfabético, también {-$^b + $^a}
lo mismo.
Si alguna vez tiene ganas de usar la sintaxis del bloque puntiagudo (like ->$a,$b {$a.map:{$_+$b}}
), es mucho mejor escribir una declaración falsa al comienzo del bloque usando ^
para cada argumento que no va a usar en el bloque principal (like {$^b;$^a.map:{$_+$b}}
) (Nota esa es la mejor manera de jugar golf {$^a.map(*+$^b)}
. Solo quería mostrar el concepto).
Los operadores son muy poderosos y, a menudo, son la forma más corta de hacer las cosas. Especialmente los meta-operadores (operadores que tienen los operadores como un argumento) []
, [\]
, X
, <<
/ >>
y Z
son dignas de su atención. No olvides que una meta-op puede tomar otra meta-op como argumento (como una XZ%%
que logré usar aquí ). También puede usarlo >>
para una llamada al método, que puede ser mucho más barato que un mapa (en @list>>.method
lugar de @list.map(*.method)
, pero tenga cuidado, ¡no son lo mismo! ). Y, finalmente, antes de usar un binario << >>
, tenga en cuenta que Z
a menudo hará lo mismo en muchos menos caracteres.
Si acumula muchas operaciones meta entre sí, puede especificar la precedencia usando corchetes []
. Eso le ahorrará cuando acumule tantos operadores que confunda al compilador. (Eso no sucede muy a menudo).
Finalmente, si necesita forzar las cosas a Bool, Int o Str, no use los métodos .Bool
, .Int
y .Str
, sino los operadores ?
, +
y ~
. O incluso mejor, simplemente póngalos en una expresión aritmética para forzarlos a Int y así sucesivamente. La forma más corta de obtener la longitud de una lista es +@list
. Si desea calcular 2 a la potencia de la longitud de una lista, simplemente diga 2**@list
y hará lo correcto.
Use las variables de estado libre $
, @
y%
En cada bloque, cada aparición de $
(o @
o %
) se refiere a una nueva variable de estado escalar (o matriz o hash) brillante (una variable cuyo valor persiste a través de las llamadas al bloque). Si necesita una variable de estado a la que solo se debe hacer referencia una vez en el código fuente, estos tres son sus grandes amigos. (La mayoría de las veces $
.) Por ejemplo, en el desafío Reverse Math Cycles , podría usarse para elegir los operadores cíclicamente de una matriz, que fue indexada por $++%6
.
Usa los sub formularios de map
, grep
et al.
Eso significa: hacer en lugar map {my block},list
de list.map({my block})
. Incluso si logra usar list.map:{my block}
, estos dos enfoques salen en el mismo número de bytes. Y a menudo, necesitaría poner entre paréntesis la lista cuando se llama a un método, pero no cuando se llama a un sub. Por lo tanto, el subenfoque sale siempre mejor o al menos igual que el método uno.
La única excepción aquí es cuando el objeto que debe ser map
ped, grep
ped , etc., está dentro $_
. Entonces .map:{}
obviamente late map {},$_
.
Use uniones ( &
y |
) en lugar de &&
y ||
.
Obviamente, son 1 byte más cortos. Por otro lado, deben colapsarse al ser forzados a un contexto booleano. Esto siempre se puede hacer con un ?
. Aquí debe tener en cuenta una meta-operación !
op
que fuerza el contexto de bool, usa op
y niega el resultado.
Si tiene una lista y desea convertirla en un cruce, no use [&]
y [|]
. En su lugar, use .any
y .all
. También hay una .none
que no puede ser tan fácilmente imitada por las operaciones de unión.
say (3² + 4², 2²⁰, 5⁻²)
==>(25 1048576 0.04)
. La lista completa de Unicode que puede abusar de esta manera está aquí: docs.perl6.org/language/unicode_texas .