Quels conseils généraux avez-vous pour jouer au golf à Perl 6? Je recherche des idées qui peuvent être appliquées aux problèmes de golf de code en général qui sont au moins quelque peu spécifiques à Perl 6 (par exemple, "supprimer les commentaires" n'est pas une réponse). Veuillez poster un pourboire par réponse.
Veuillez noter que Perl 6 n'est pas Perl 5, donc cette question n'est pas un doublon. La plupart des conseils pour le golf Perl 5 ne s'appliquent tout simplement pas à Perl 6.
say (3² + 4², 2²⁰, 5⁻²)
==>(25 1048576 0.04)
. La liste complète d'Unicode que vous pouvez abuser comme ceci est ici: docs.perl6.org/language/unicode_texas .Apprenez les fonctions pour lire l'entrée. Perl 6 a de nombreuses fonctions intéressantes qui peuvent facilement lire l'entrée d'ARGV ou STDIN (si rien n'a été spécifié sur ARGV), ce qui peut raccourcir votre code s'il est utilisé correctement. Si vous les appelez en tant que méthodes de
STDIN
descripteur de fichier , vous pouvez les forcer à travailler sur un descripteur de fichier particulier (utile si vous lisez par exemple , mais que vous devez lire des arguments sur ARGV).get
Cette fonction obtient une seule ligne et la coupe automatiquement, vous n'avez donc pas à le faire. Ceci est utile si vous devez lire une seule ligne.
lines
Cette fonction récupère toutes les lignes du fichier ou STDIN. C'est une liste paresseuse, donc si vous l'utilisez avec
for
, elle ne lira que ce dont vous avez besoin. Par exemple.slurp
Cela lira le fichier entier ou STDIN et renverra le résultat sous la forme d'une seule chaîne.
la source
say "<$_>" for lines
fonctionne maintenantAvertissement : le mur de texte approche. C'est beaucoup de petites astuces que j'ai rassemblées au fil du temps.
Écrivez vos solutions sous forme de blocs anonymes
Cela a déjà été mentionné, mais je voudrais le répéter. Dans TIO, vous pouvez écrire
my $f =
dans l'en-tête, le bloc dans le code approprié et démarrer le pied de page avec a;
. Cela semble être de loin le moyen le plus court pour faire le travail (puisque vous n'avez pas besoin de vous soucier de la lecture d'une entrée, elle vous est donnée dans les arguments).Une autre bonne façon d'utiliser le
-n
ou le-p
commutateur, mais je n'ai pas trouvé de moyen de le faire fonctionner dans TIO.Utilisez la syntaxe deux-points pour passer des arguments
Autrement dit, au lieu de
thing.method(foo,bar)
, vous pouvez fairething.method:foo,bar
et enregistrer 1 caractère. Malheureusement, vous ne pouvez pas appeler une autre méthode sur le résultat pour des raisons évidentes, il est donc logique de ne l'utiliser que pour la dernière méthode d'un bloc.Utilisez
$_
autant que vous le pouvezIl est parfois préférable de prendre un seul argument de liste que plusieurs arguments distincts à cause de cela. Lors de l'accès
$_
, vous pouvez appeler des méthodes dessus simplement en commençant par un point: eg.sort
est égal à$_.sort
.Cependant, gardez à l'esprit que chaque bloc obtient le sien
$_
, de sorte que les paramètres du bloc externe ne se propageront pas dans les blocs internes. Si vous devez accéder aux paramètres de la fonction principale à partir d'un bloc interne, ...Utilisez les
^
variables si vous ne pouvez pas utiliser$_
Insérez un
^
entre le Sigil et le nom de la variable, comme ceci:$^a
. Ceux-ci ne fonctionnent qu'à l'intérieur d'un bloc. Le compilateur compte d'abord combien vous en avez dans le bloc, les trie lexicographiquement, puis attribue le premier argument au premier, le second au second et ainsi de suite. Le^
doit être utilisé uniquement lors de la première occurrence de la variable. Prend donc{$^a - $^b}
2 scalaires et les soustrait. La seule chose qui compte est l'ordre alphabétique, tout{-$^b + $^a}
comme la même chose.Si jamais vous avez envie d'utiliser la syntaxe de bloc pointu (comme
->$a,$b {$a.map:{$_+$b}}
), vous feriez bien mieux d'écrire une déclaration fausse au début du bloc en utilisant le^
pour chaque argument que vous n'allez pas utiliser dans le bloc principal (comme{$^b;$^a.map:{$_+$b}}
) (Remarque c'est la meilleure façon de jouer au golf{$^a.map(*+$^b)}
. Je voulais juste montrer le concept.)Lisez attentivement les documents de l' opérateur
Les opérateurs sont très puissants et sont souvent le moyen le plus court de faire avancer les choses. En particulier , les méta-opérateurs (opérateurs qui prennent des opérateurs comme argument)
[]
,[\]
,X
,<<
/>>
etZ
méritent votre attention. N'oubliez pas qu'une méta-op peut prendre comme argument une autre méta-op (comme celle queXZ%%
j'ai réussi à utiliser ici ). Vous pouvez également utiliser>>
pour un appel de méthode, ce qui peut être beaucoup moins cher qu'une carte (@list>>.method
au lieu de@list.map(*.method)
, mais attention, ce n'est pas pareil! ). Et, enfin, avant d'utiliser un binaire<< >>
, gardez à l'esprit que celaZ
fera souvent la même chose avec beaucoup moins de caractères.Si vous amassez beaucoup de méta-opérations les unes sur les autres, vous pouvez spécifier la priorité à l'aide de crochets
[]
. Cela vous épargnera lorsque vous empilerez autant d'opérateurs que cela confond le compilateur. (Cela n'arrive pas très souvent.)Enfin, si vous avez besoin de choses à COERCE Bool, Int ou Str, ne pas utiliser les méthodes
.Bool
,.Int
et.Str
, mais les opérateurs?
,+
et~
. Ou encore mieux, il suffit de les mettre dans une expression arithmétique pour les forcer dans Int et ainsi de suite. Le moyen le plus court pour obtenir la longueur d'une liste est+@list
. Si vous voulez calculer 2 à la puissance de la longueur d'une liste, dites simplement2**@list
et cela fera la bonne chose.Utilisez les variables d'état libre
$
,@
et%
Dans chaque bloc, chaque occurrence de
$
(ou@
ou%
) fait référence à une nouvelle variable d'état scalaire (ou tableau ou hachage) brillante (une variable dont la valeur persiste pendant les appels au bloc). Si vous avez besoin d'une variable d'état qui ne doit être référencée qu'une seule fois dans le code source, ces trois sont vos grands amis. (Le plus souvent le$
.) Par exemple, dans le défi Cycles mathématiques inversés , il pourrait être utilisé pour choisir les opérateurs de façon cyclique dans un tableau, qui a été indexé par$++%6
.Utilisez les sous-formes de
map
,grep
et al.Cela signifie: faire plutôt
map {my block},list
quelist.map({my block})
. Même si vous parvenez à utiliserlist.map:{my block}
, ces deux approches sortent au même nombre d'octets. Et souvent, vous devrez mettre la liste entre parenthèses lors de l'appel d'une méthode, mais pas lors de l'appel d'un sous. Ainsi, la sous-approche ressort toujours meilleure ou au moins la même que celle de la méthode.La seule exception ici est lorsque l'objet qui doit être
map
ped,grep
ped et ainsi de suite, est dedans$_
. Alors,.map:{}
évidemment, batmap {},$_
.Utilisez les jonctions (
&
et|
) au lieu de&&
et||
.De toute évidence, ils sont plus courts de 1 octet. En revanche, ils doivent s'effondrer en étant contraints dans un contexte booléen. Cela peut toujours être fait avec un
?
. Ici, vous devez être conscient d'une méta-op!
op
qui force le contexte booléen, utiliseop
et annule le résultat.Si vous avez une liste et que vous souhaitez la transformer en jonction, n'utilisez pas
[&]
et[|]
. Utilisez plutôt.any
et.all
. Il y en a aussi.none
qui ne peuvent pas être si facilement imités par les opérations de jonction.la source
&&
et||
sont toujours utiles pour les courts-circuits?Réduisez l'espace utilisé pour les variables
Il y a quelques parties à cela.
Supprimer les espaces
Les variables déclarées à l'aide
my
peuvent généralement être déclarées sans l'espace entremy
et le nom de la variable.my @a
est équivalent àmy@a
.Utiliser des variables sans cachet
Vous pouvez déclarer des variables à l'aide d'une barre oblique inverse pour supprimer le sceau avant le nom de la variable, comme ceci:
(malheureusement, vous ne pouvez pas supprimer l'espace :()
Ceci est utile car vous pouvez ensuite vous y référer comme étant simplement le nom de la variable nue.
Fondamentalement, cela économise des octets si vous utilisez la variable plus d'une fois ailleurs dans votre code. L'inconvénient est que la variable doit être initialisée.
Utiliser
$!
et$/
Ces variables pré-déclarées sont généralement utilisées pour les exceptions et les correspondances d'expression rationnelle respectivement, mais n'ont pas besoin d'être définies à l'aide de
my
.Il est particulièrement utile d'utiliser
$/
comme tableau et d'utiliser les raccourcis$
suivis d'un nombre pour accéder à cet élément du$/
tableau;la source
Utiliser
...
au lieu defirst
En règle générale, si vous souhaitez trouver le premier nombre correspondant à une condition
&f
, vous pouvez le représenter comme:Cependant, à la place, vous pouvez utiliser l'
...
opérateur:Si vous devez partir de là
0
, vous pouvez en avoir-1
après au lieu de+
.Si vous voulez que l'index du premier élément d'une liste
@a
qui ait une condition&f
, vous le faites normalement:Au lieu:
(ou vice versa si vous voulez 0 indexé). De la même manière, vous pouvez obtenir tous les éléments jusqu'au premier qui passe la condition.
L'inconvénient est que la liste doit passer la condition à un moment donné, sinon l'
...
opérateur tentera d'extrapoler à la fin de la liste et générera très probablement une erreur. Vous ne pouvez pas non plus utiliser n'importe quel code dans la partie gauche, car il serait interprété comme faisant partie de la séquence.la source