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 -n
o 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 Z
sono 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>>.method
invece di @list.map(*.method)
, ma attenzione, non sono uguali! ). E, infine, prima di usare un binario << >>
, tieni presente che Z
spesso 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
, .Int
e .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**@list
che 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
, grep
et al.
Ciò significa: fare piuttosto map {my block},list
che 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 map
ped, grep
ped 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 !
op
che forza il contesto bool, usa op
e nega il risultato.
Se hai un elenco e vuoi trasformarlo in un incrocio, non usare [&]
e [|]
. Invece usa .any
e .all
. C'è anche .none
che 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 .