Aviso : parede de texto se aproximando. São muitos truques pequenos que reuni ao longo do tempo.
Escreva suas soluções como blocos anônimos
Isso já foi mencionado, mas eu gostaria de reiterar. No TIO, você pode escrever my $f =
no cabeçalho, o bloco no código apropriado e iniciar o rodapé com a ;
. Essa parece ser de longe a maneira mais curta de realizar o trabalho (já que você não precisa se preocupar em ler nenhuma entrada, ela é fornecida nos argumentos).
Outra maneira interessante é usar o switch -n
ou o -p
switch, mas não encontrei uma maneira de fazê-lo funcionar no TIO.
Use a sintaxe dos dois pontos para passar argumentos
Ou seja, em vez de thing.method(foo,bar)
, você pode fazer thing.method:foo,bar
e salvar 1 caractere. Infelizmente, você não pode chamar outro método no resultado por razões óbvias; portanto, faz sentido usar apenas o último método em um bloco.
Use $_
o máximo que puder
Às vezes, é melhor usar um argumento de lista única do que vários argumentos separados por causa disso. Ao acessar $_
, você pode chamar métodos apenas começando com um ponto: por exemplo, .sort
é igual a$_.sort
.
No entanto, lembre-se de que cada bloco recebe o seu $_
, para que os parâmetros do bloco externo não se propaguem para os internos. Se você precisar acessar os parâmetros da função principal a partir de um bloco interno, ...
Use as ^
variáveis se você não puder usar$_
Inserir um ^
entre o sigilo eo nome da variável, como este: $^a
. Estes funcionam apenas dentro de um bloco. O compilador primeiro conta quantas delas você possui no bloco, as classifica lexicograficamente e depois atribui o primeiro argumento ao primeiro, o segundo ao segundo e assim por diante. O ^
precisa ser usado apenas na primeira ocorrência da variável. Então {$^a - $^b}
pega dois escalares e os subtrai. A única coisa que importa é a ordem alfabética, {-$^b + $^a}
o mesmo acontece.
Se você sentir vontade de usar a sintaxe do bloco pontudo (como ->$a,$b {$a.map:{$_+$b}}
), é muito melhor escrever uma declaração falsa no início do bloco usando o ^
para cada argumento que não será usado no bloco principal (como {$^b;$^a.map:{$_+$b}}
) (Observação) essa é a melhor maneira de jogar golfe {$^a.map(*+$^b)}
. Eu só queria mostrar o conceito.)
Os operadores são muito poderosos e geralmente são a maneira mais curta de fazer as coisas. Especialmente os meta-operadores (operadores que levam operadores como um argumento) []
, [\]
, X
, <<
/ >>
e Z
valem de sua atenção. Não esqueça que uma meta-op pode XZ%%
usar outra meta-op como argumento (como uma que eu consegui usar aqui ). Você também pode usar >>
uma chamada de método, que pode ser muito mais barata que um mapa (em @list>>.method
vez de @list.map(*.method)
, mas cuidado, elas não são iguais! ). E, finalmente, antes de usar um binário << >>
, lembre-se de que Z
muitas vezes fará a mesma coisa em muito menos caracteres.
Se você agrupar várias meta-ops, poderá especificar a precedência usando colchetes []
. Isso economizará você quando você empilha tantos operadores que confunde o compilador. (Isso não acontece com muita frequência.)
Finalmente, se você precisa de coisas coagir a Bool, Int ou Str, não use os métodos .Bool
, .Int
e .Str
, mas sim os operadores ?
, +
e ~
. Ou melhor ainda, basta colocá-los em uma expressão aritmética para forçá-los a Int e assim por diante. A maneira mais curta de obter o comprimento de uma lista é +@list
. Se você deseja calcular 2 com base no comprimento de uma lista, basta dizer 2**@list
e ele fará a coisa certa.
Use as variáveis de estado livre $
, @
e%
Em cada bloco, toda ocorrência de $
(ou @
ou %
) refere-se a uma nova variável de estado escalar (ou matriz ou hash) brilhante (uma variável cujo valor persiste nas chamadas para o bloco). Se você precisar de uma variável de estado que precise ser referenciada apenas uma vez no código-fonte, esses três serão seus grandes amigos. (Na maioria das vezes, o $
.) Por exemplo, no desafio Ciclos matemáticos reversos , ele poderia ser usado para escolher os operadores ciclicamente a partir de uma matriz, que foi indexada por $++%6
.
Use as sub-formas de map
, grep
et al.
Isso significa: faça em vez map {my block},list
de list.map({my block})
. Mesmo se você conseguir usar list.map:{my block}
, essas duas abordagens serão exibidas no mesmo número de bytes. E, frequentemente, você precisaria colocar parênteses na lista ao chamar um método, mas não ao chamar um sub. Portanto, a sub abordagem é sempre melhor ou pelo menos a mesma do método.
A única exceção aqui é quando o objeto que deve ser map
ped, grep
ped e assim por diante, é no $_
. Então, .map:{}
obviamente, bate map {},$_
.
Use junções ( &
e |
) em vez de &&
e ||
.
Obviamente, eles são 1 byte mais curto. Por outro lado, eles devem ser recolhidos ao serem forçados a um contexto booleano. Isso sempre pode ser feito com a ?
. Aqui você deve estar ciente de uma meta-op !
op
que força o contexto bool, usa op
e nega o resultado.
Se você tem uma lista e deseja transformá-la em uma junção, não use [&]
e [|]
. Em vez disso, use .any
e .all
. Há também os .none
que não podem ser tão facilmente imitados pelas operações de junção.
say (3² + 4², 2²⁰, 5⁻²)
==>(25 1048576 0.04)
. A lista completa de Unicode que você pode abusar assim está aqui: docs.perl6.org/language/unicode_texas .