Avvertenza : muro di testo in avvicinamento. Sono molti i piccoli trucchi che ho raccolto nel tempo.
Scrivi le tue soluzioni come blocchi anonimi
Questo è già stato menzionato, ma vorrei ribadirlo. In TIO, è possibile scrivere my $f =nell'intestazione, il blocco nel codice corretto e avviare il piè di pagina con a; . Questo sembra essere di gran lunga il modo più breve per portare a termine il lavoro (poiché non devi preoccuparti di leggere alcun input, ti viene dato negli argomenti).
Un altro modo carino è usare il -no il-p , ma non ho trovato un modo per farlo funzionare in TIO.
Utilizzare la sintassi dei due punti per passare argomenti
Cioè, invece di thing.method(foo,bar), puoi farething.method:foo,bar e salvare 1 carattere. Sfortunatamente, non puoi chiamare un altro metodo sul risultato per ovvi motivi, quindi ha senso usare solo l'ultimo metodo in un blocco.
Uso $_ il più possibile
A volte è meglio prendere un singolo argomento dell'elenco piuttosto che diversi argomenti separati per questo motivo. Quando si accede $_, è possibile chiamare metodi su di esso solo iniziando con un punto: eg .sortè uguale a$_.sort .
Tuttavia, tieni presente che ogni blocco ottiene il suo $_, quindi i parametri del blocco esterno non si propagheranno in quelli interni. Se è necessario accedere ai parametri della funzione principale da un blocco interno, ...
Usa le ^variabili se non puoi usarle$_
Inserire una ^tra il sigillo e il nome della variabile, in questo modo: $^a. Funzionano solo all'interno di un blocco. Il compilatore conta prima quanti di questi hai nel blocco, li ordina lessicograficamente e quindi assegna il primo argomento al primo, il secondo al secondo e così via. Le ^esigenze da utilizzare solo nella prima occorrenza della variabile. Quindi {$^a - $^b}prende 2 scalari e li sottrae. L'unica cosa che conta è l'ordine alfabetico, così {-$^b + $^a}fa la stessa cosa.
Se hai mai voglia di usare la sintassi del blocco appuntito (come ->$a,$b {$a.map:{$_+$b}}), è molto meglio scrivere un'istruzione fasulla all'inizio del blocco usando il ^per ogni argomento che non userai nel blocco principale (come {$^b;$^a.map:{$_+$b}}) (Nota questo è il modo migliore per giocare a golf {$^a.map(*+$^b)}. Volevo solo mostrare il concetto.)
Gli operatori sono molto potenti e spesso sono il modo più breve per fare le cose. Soprattutto i meta-operatori (operatori che prendono gli operatori come argomento) [], [\], X, <</ >>e Zsono valore della vostra attenzione. Non dimenticare che una meta-op può prendere un'altra meta-op come argomento (come una che XZ%%sono riuscito a usare qui ). Puoi anche usarlo >>per una chiamata di metodo, che può essere molto più economica di una mappa ( @list>>.methodinvece di @list.map(*.method), ma attenzione, non sono uguali! ). E, infine, prima di usare un binario << >>, tieni presente che Zspesso farà la stessa cosa in molti meno personaggi.
Se si accumulano molte meta-op l'una sull'altra, è possibile specificare la precedenza utilizzando parentesi quadre []. Ciò ti salverà quando accumuli così tanti operatori che confonde il compilatore. (Ciò non accade molto spesso.)
Infine, se avete bisogno di cose costringere a Bool, Int o Str, non si utilizzano i metodi .Bool, .Inte .Str, quanto piuttosto gli operatori ?, +e ~. O ancora meglio, basta metterli in un'espressione aritmetica per forzarli in Int e così via. Il modo più breve per ottenere la lunghezza di un elenco è +@list. Se vuoi calcolare 2 in base alla potenza della lunghezza di un elenco, dì solo 2**@listche farà la cosa giusta.
Utilizzare le variabili di stato libero $, @e%
In ogni blocco, ogni occorrenza di $(o @o %) si riferisce a una nuova brillante variabile di stato scalare (o array o hash) (una variabile il cui valore persiste attraverso le chiamate al blocco). Se hai bisogno di una variabile di stato a cui devi fare riferimento una sola volta nel codice sorgente, questi tre sono i tuoi grandi amici. (Molto spesso il $.) Ad esempio, nella sfida Reverse Math Cycles , potrebbe essere usato per scegliere ciclicamente gli operatori da un array, che è stato indicizzato da $++%6.
Usa i sottoformi di map, grepet al.
Ciò significa: fare piuttosto map {my block},listche list.map({my block}). Anche se riesci a usare list.map:{my block}, questi due approcci escono allo stesso numero di byte. E spesso, è necessario racchiudere tra parentesi l'elenco quando si chiama un metodo, ma non quando si chiama un sub. Quindi l'approccio secondario risulta sempre migliore o almeno uguale a quello del metodo.
L'unica eccezione qui è quando l'oggetto che deve essere mapped, grepped e così via, è dentro $_. Quindi .map:{}ovviamente batte map {},$_.
Utilizzare giunzioni ( &e |) anziché &&e ||.
Ovviamente, sono più brevi di 1 byte. D'altra parte, devono essere collassati per essere costretti in un contesto booleano. Questo può essere sempre fatto con a ?. Qui dovresti essere consapevole di una meta-op !opche forza il contesto bool, usa ope nega il risultato.
Se hai un elenco e vuoi trasformarlo in un incrocio, non usare [&]e [|]. Invece usa .anye .all. C'è anche .noneche non può essere così facilmente imitato dalle operazioni di giunzione.
say (3² + 4², 2²⁰, 5⁻²)==>(25 1048576 0.04). L'elenco completo di Unicode che puoi abusare in questo modo è qui: docs.perl6.org/language/unicode_texas .