Warnung : Textwand nähert sich. Es sind viele kleine Tricks, die ich im Laufe der Zeit gesammelt habe.
Schreiben Sie Ihre Lösungen als anonyme Blöcke
Dies wurde bereits erwähnt, aber ich möchte es wiederholen. In TIO können Sie my $f =
in den Header und den Block in den Code schreiben und die Fußzeile mit einem beginnen ;
. Dies scheint bei weitem der kürzeste Weg zu sein, um die Arbeit zu erledigen (da Sie sich nicht um das Lesen von Eingaben kümmern müssen, wird dies in den Argumenten angegeben).
Eine andere gute Möglichkeit ist die Verwendung des Schalters -n
oder -p
, aber ich habe keine Möglichkeit gefunden, ihn in TIO zum Laufen zu bringen.
Verwenden Sie die Doppelpunktsyntax zum Übergeben von Argumenten
Das heißt, stattdessen thing.method(foo,bar)
können Sie thing.method:foo,bar
1 Zeichen ausführen und speichern. Leider können Sie aus offensichtlichen Gründen keine andere Methode für das Ergebnis aufrufen. Daher ist es sinnvoll, nur die letzte Methode in einem Block zu verwenden.
Verwenden Sie $_
so viel wie möglich
Manchmal ist es aus diesem Grund besser, ein einzelnes Listenargument als mehrere separate Argumente zu verwenden. Beim Zugriff $_
können Sie Methoden aufrufen, indem Sie mit einem Punkt beginnen: zB .sort
ist gleich $_.sort
.
Bedenken Sie jedoch, dass jeder Block seinen eigenen erhält $_
, damit die Parameter des äußeren Blocks nicht in den inneren übertragen werden. Wenn Sie von einem inneren Block aus auf die Parameter der Hauptfunktion zugreifen müssen, ...
Verwenden Sie die ^
Variablen, wenn Sie sie nicht verwenden können$_
Legen Sie eine ^
zwischen dem Sigil und dem Variablennamen, wie folgt aus : $^a
. Diese funktionieren nur innerhalb eines Blocks. Der Compiler zählt zuerst, wie viele davon Sie im Block haben, sortiert sie lexikografisch und weist dann dem ersten das erste Argument zu, dem zweiten das zweite und so weiter. Das ^
muss nur beim ersten Auftreten der Variablen verwendet werden. Nimmt also {$^a - $^b}
2 Skalare und subtrahiert sie. Das Einzige, was zählt, ist die alphabetische Reihenfolge, {-$^b + $^a}
genau wie das Gleiche.
Wenn Sie jemals Lust haben, die Syntax für spitze Blöcke (wie ->$a,$b {$a.map:{$_+$b}}
) zu verwenden, ist es weitaus besser, falsche Anweisungen am Anfang des Blocks zu schreiben, indem Sie ^
für jedes Argument, das Sie nicht im Hauptblock verwenden möchten (wie {$^b;$^a.map:{$_+$b}}
) (Anmerkung Das ist der bessere Weg, Golf zu spielen {$^a.map(*+$^b)}
. Ich wollte nur das Konzept vorführen.)
Die Bediener sind sehr mächtig und oft der kürzeste Weg, um Dinge zu erledigen. Insbesondere die Meta-Operatoren (Operatoren, die Operatoren als Argument nehmen) []
,[\]
, X
, <<
/ >>
und Z
ist es wert , Ihre Aufmerksamkeit. Vergessen Sie nicht, dass ein Meta-Op ein anderes Meta-Op als Argument verwenden kann (wie XZ%%
ich es hier geschafft habe ). Sie können sie auch >>
für einen Methodenaufruf verwenden, der viel billiger ist als eine Karte ( @list>>.method
anstatt @list.map(*.method)
, aber Vorsicht, sie sind nicht gleich! ). Und bevor Sie schließlich eine Binärdatei verwenden << >>
, sollten Sie bedenken, dass dies Z
häufig in viel weniger Zeichen der Fall ist.
Wenn Sie viele Meta-Ops aufeinander häufen, können Sie die Priorität in eckigen Klammern angeben []
. Das erspart Ihnen, wenn Sie so viele Operatoren anhäufen, dass der Compiler verwirrt wird. (Das kommt nicht sehr oft vor.)
Schließlich, wenn Sie brauchen , um coerce Dinge Bool, Int oder Str, nicht die Methoden verwenden .Bool
, .Int
und .Str
, sondern die Betreiber ?
, +
und ~
. Oder noch besser, setzen Sie sie einfach in einen arithmetischen Ausdruck, um sie in Int und so weiter zu zwingen. Der kürzeste Weg, um die Länge einer Liste zu ermitteln, ist +@list
. Wenn Sie 2 hoch der Länge einer Liste berechnen möchten, sagen 2**@list
Sie einfach und es wird das Richtige tun.
Verwenden Sie die freien Zustandsvariablen $
, @
und%
In jedem Block jedes Vorkommen von $
bezieht sich (oder @
oder %
) auf eine glänzende neue skalare (oder Array- oder Hash-) Zustandsvariable (eine Variable, deren Wert bei bleibt). Wenn Sie eine Statusvariable benötigen, auf die nur einmal im Quellcode verwiesen werden muss, sind diese drei Ihre großen Freunde. (Meistens das $
.) Zum Beispiel könnte es bei der Challenge Reverse Math Cycles verwendet werden, um die Operatoren zyklisch aus einem Array auszuwählen, das von indexiert wurde $++%6
.
Mithilfe der Unterformen map
, grep
et al.
Das heißt: lieber tun map {my block},list
als list.map({my block})
. Selbst wenn Sie es schaffen list.map:{my block}
, werden diese beiden Ansätze mit der gleichen Anzahl von Bytes ausgegeben. Und häufig müssen Sie die Liste beim Aufrufen einer Methode in Klammern setzen, nicht jedoch beim Aufrufen einer Sub-Methode. So kommt der Unteransatz immer besser heraus oder zumindest genauso wie die Methode eins.
Die einzige Ausnahme ist hier, wann das Objekt sein soll map
ped, grep
ped usw. sein soll, in befindet $_
. Dann .map:{}
schlägt offensichtlich map {},$_
.
Verwenden Sie Junctions ( &
und |
) anstelle von &&
und ||
.
Offensichtlich sind sie 1 Byte kürzer. Andererseits müssen sie zusammengebrochen werden, indem sie in einen booleschen Kontext gezwungen werden. Dies kann immer mit a erfolgen ?
. Hier sollten Sie auf ein Meta-Op achten!
op
Ops das den Bool-Kontext erzwingt, op
das Ergebnis verwendet und negiert.
Wenn Sie eine Liste haben und diese in eine Junction verwandeln möchten, verwenden Sie [&]
und nicht [|]
. Verwenden Sie stattdessen .any
und .all
. Es gibt auch .none
solche, die von den Junction Ops nicht so einfach nachgeahmt werden können.
say (3² + 4², 2²⁰, 5⁻²)
==>(25 1048576 0.04)
. Die vollständige Liste von Unicode, die Sie so missbrauchen können, finden Sie hier: docs.perl6.org/language/unicode_texas .