Welche allgemeinen Tipps haben Sie zum Golfen in Perl 6? Ich bin auf der Suche nach Ideen, die sich auf Code-Golf-Probleme im Allgemeinen anwenden lassen, die zumindest etwas spezifisch für Perl 6 sind (z. B. "Kommentare entfernen" ist keine Antwort). Bitte posten Sie einen Tipp pro Antwort.
Bitte beachten Sie, dass Perl 6 nicht Perl 5 ist, daher handelt es sich bei dieser Frage nicht um ein Duplikat. Die meisten Tipps zum Golfen mit Perl 5 gelten nicht für Perl 6.
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 .Lernen Sie die Funktionen zum Lesen der Eingabe. Perl 6 verfügt über viele interessante Funktionen, mit denen die Eingabe von ARGV oder STDIN (sofern in ARGV nichts angegeben wurde) leicht gelesen werden kann. Bei korrekter Verwendung kann dies Ihren Code verkürzen. Wenn Sie sie als Dateihandle-Methoden aufrufen, können Sie sie zwingen, mit einem bestimmten Dateihandle zu arbeiten (nützlich, wenn Sie beispielsweise aus lesen
STDIN
, aber Argumente in ARGV lesen müssen).get
Diese Funktion erhält eine einzelne Zeile und kaut diese automatisch, sodass Sie dies nicht tun müssen. Dies ist nützlich, wenn Sie nur eine Zeile lesen müssen.
lines
Diese Funktion holt alle Zeilen aus der Datei oder STDIN. Es ist eine faule Liste. Wenn Sie sie also mit verwenden
for
, wird nur das gelesen, was Sie benötigen. Beispielsweise.slurp
Dadurch wird die gesamte Datei oder STDIN gelesen und das Ergebnis als einzelne Zeichenfolge zurückgegeben.
quelle
say "<$_>" for lines
funktioniert aber jetztWarnung : 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 Siething.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öglichManchmal 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.)Lesen Sie die Bedienungsanleitungen sorgfältig durch
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
,<<
/>>
undZ
ist es wert , Ihre Aufmerksamkeit. Vergessen Sie nicht, dass ein Meta-Op ein anderes Meta-Op als Argument verwenden kann (wieXZ%%
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 diesZ
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, sagen2**@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
alslist.map({my block})
. Selbst wenn Sie es schaffenlist.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 offensichtlichmap {},$_
.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.quelle
&&
und bin||
immer noch nützlich zum Kurzschließen?Reduzieren Sie den für Variablen verwendeten Speicherplatz
Es gibt ein paar Teile dazu.
Leerzeichen entfernen
Mit deklarierte Variablen
my
können normalerweise ohne das Leerzeichen zwischenmy
und dem Variablennamen deklariert werden .my @a
ist äquivalent zumy@a
.Verwenden Sie Variablen ohne Siegel
Sie können Variablen mit einem Backslash deklarieren, um das Siegel vor dem Variablennamen zu entfernen.
(das Leerzeichen kann leider nicht entfernt werden :()
Dies ist nützlich, da Sie sie später nur als bloßen Variablennamen bezeichnen können.
Grundsätzlich werden dadurch Bytes gespart, wenn Sie die Variable mehrmals an einer anderen Stelle im Code verwenden. Der Nachteil ist, dass die Variable initialisiert werden muss.
Verwenden Sie
$!
und$/
Diese vordeklarierten Variablen werden normalerweise für Ausnahmen bzw. reguläre Ausdrücke verwendet, müssen jedoch nicht mit definiert werden
my
.Besonders nützlich ist die Verwendung
$/
als Array und die Verwendung der Verknüpfungen,$
gefolgt von einer Zahl, um auf dieses Element des$/
Arrays zuzugreifen .quelle
Verwenden Sie
...
anstelle vonfirst
In der Regel können Sie die erste Zahl, die einer Bedingung entspricht
&f
, folgendermaßen darstellen:Sie können jedoch stattdessen die
...
Operator verwenden:Wenn Sie anfangen müssen
0
, können Sie haben-1
danach statt+
.Wenn Sie den Index des ersten Elements in einer Liste
@a
mit Bedingungen&f
anzeigen möchten , gehen Sie normalerweise wie folgt vor:Stattdessen:
(oder umgekehrt, wenn 0 indiziert werden soll). Auf die gleiche Weise können Sie alle Elemente bis zu dem ersten Element abrufen, das die Bedingung erfüllt.
Nachteile hierfür ist , dass die Liste hat den Zustand irgendwann passieren, sonst wird der
...
Betreiber versucht , über das Ende der Liste zu extrapolieren, und höchstwahrscheinlich einen Fehler aus. Sie können auch keinen beliebigen Code auf der linken Seite verwenden, da dieser als Teil der Sequenz interpretiert wird.quelle