Ostrzeżenie : zbliża się ściana tekstu. Z czasem zebrałem wiele małych sztuczek.
Napisz swoje rozwiązania jako anonimowe bloki
Zostało to już wspomniane, ale chciałbym to powtórzyć. W TIO możesz pisać my $f =
w nagłówku, blok w odpowiednim kodzie i zaczynać stopkę od;
. Wydaje się, że jest to zdecydowanie najkrótszy sposób na wykonanie zadania (ponieważ nie musisz przejmować się czytaniem jakichkolwiek danych wejściowych, są one podawane w argumentach).
Innym fajnym sposobem jest użycie przełącznika -n
lub -p
, ale nie znalazłem sposobu, aby działał w TIO.
Do przekazywania argumentów używaj składni dwukropka
Oznacza to, thing.method(foo,bar)
że możesz zrobić thing.method:foo,bar
i zapisać 1 postać. Niestety nie można wywołać innej metody z wyniku z oczywistych powodów, dlatego warto używać tylko ostatniej metody w bloku.
Używaj $_
jak najwięcej
Czasami lepiej jest z tego powodu wziąć jeden argument listy niż kilka oddzielnych argumentów. Podczas uzyskiwania dostępu $_
możesz wywoływać na nim metody, zaczynając od kropki: np. .sort
Jest równa$_.sort
.
Pamiętaj jednak, że każdy blok ma swój własny $_
, więc parametry bloku zewnętrznego nie będą się rozchodzić do wewnętrznych. Jeśli chcesz uzyskać dostęp do parametrów funkcji głównej z wewnętrznego bloku, ...
Użyj ^
zmiennych, jeśli nie możesz użyć$_
Włóż ^
między sigil i nazwy zmiennej, na przykład: $^a
. Działają one tylko wewnątrz bloku. Kompilator najpierw zlicza ich liczbę w bloku, sortuje je leksykograficznie, a następnie przypisuje pierwszy argument do pierwszego, drugi do drugiego i tak dalej. The^
z niego korzystać tylko przy pierwszym wystąpieniu zmiennej. Więc {$^a - $^b}
bierze 2 skalary i odejmuje je. Liczy się tylko kolejność alfabetyczna, podobnie {-$^b + $^a}
jak to samo.
Jeśli kiedykolwiek masz ochotę użyć spiczastej składni bloku (jak ->$a,$b {$a.map:{$_+$b}}
), o wiele lepiej jest napisać fałszywą instrukcję na początku bloku, używając ^
dla każdego argumentu, którego nie będziesz używać w bloku głównym (jak{$^b;$^a.map:{$_+$b}}
) (Uwaga) jest to lepszy sposób na golfa {$^a.map(*+$^b)}
. Chciałem tylko pochwalić się tą koncepcją.)
Operatorzy są bardzo potężni i często są najkrótszym sposobem na załatwienie sprawy. Zwłaszcza meta-operatorzy (operatorów, które mają operatorów jako argument) []
, [\]
, X
, <<
/ >>
i Z
są warte Twojej uwagi. Nie zapominaj, że meta-op może podjąć inną meta-op jako argument (jak XZ%%
udało mi się użyć tutaj ). Możesz także użyć >>
wywołania metody, które może być znacznie tańsze niż mapa ( @list>>.method
zamiast @list.map(*.method)
, ale uwaga, to nie to samo! ). I wreszcie, zanim użyjesz pliku binarnego << >>
, pamiętaj o tymZ
często robi to samo przy znacznie mniejszej liczbie znaków.
Jeśli nakładasz na siebie wiele metaoperacji, możesz określić pierwszeństwo za pomocą nawiasów kwadratowych []
. Dzięki temu zaoszczędzisz, gdy zgromadzisz tak wiele operatorów, że dezorientuje to kompilator. (To nie zdarza się często.)
W końcu, jeśli trzeba zmusić warte Bool, int lub STR, nie używać metod .Bool
, .Int
a .Str
, ale operatorzy ?
, +
a ~
. Lub jeszcze lepiej, po prostu wprowadź je do wyrażenia arytmetycznego, aby zmusić je do Int i tak dalej. Najkrótszym sposobem na uzyskanie długości listy jest +@list
. Jeśli chcesz obliczyć 2 do potęgi długości listy, po prostu powiedz, 2**@list
a zrobi to The Right Thing.
Użyj zmiennych stanu swobodnego $
,@
i%
W każdym bloku każde wystąpienie $
(lub @
lub %
) odnosi się do nowej błyszczącej zmiennej stanu skalarnego (lub tablicy lub skrótu) (zmiennej, której wartość utrzymuje się podczas wywołań bloku). Jeśli potrzebujesz zmiennej stanu, do której należy odwoływać się tylko raz w kodzie źródłowym, te trzy są twoimi wielkimi przyjaciółmi. (Najczęściej $
.) Na przykład w wyzwaniu Odwrotne cykle matematyczne można go użyć do cyklicznego wybierania operatorów z tablicy, która została zindeksowana $++%6
.
Skorzystaj z podform map
, grep
i in.
To znaczy: raczej rób map {my block},list
niż list.map({my block})
. Nawet jeśli uda ci się użyćlist.map:{my block}
, te dwa podejścia mają tę samą liczbę bajtów. I często trzeba wywoływać listę w nawiasie podczas wywoływania metody, ale nie podczas wywoływania podrzędnego. Tak więc podejście podrzędne wychodzi zawsze lepiej lub przynajmniej tak samo jak metoda pierwsza.
Jedynym wyjątkiem jest sytuacja, w której znajduje się obiekt, który ma być map
ped, grep
ped i tak dalej $_
. Wtedy .map:{}
oczywiście bije map {},$_
.
Użyj skrzyżowań ( &
i |
) zamiast &&
i ||
.
Oczywiście są one o 1 bajt krótsze. Z drugiej strony należy je zwinąć, zmuszając je do kontekstu logicznego. Można to zawsze zrobić za pomocą ?
. Tutaj powinieneś zdawać sobie sprawę z meta-op, !
op
która wymusza kontekst bool, używaop
i neguje wynik.
Jeśli masz listę i chcesz zamienić ją w skrzyżowanie, nie używaj [&]
i [|]
. Zamiast tego użyj .any
i .all
. Są też takie, .none
których nie da się tak łatwo naśladować w połączeniach.
say (3² + 4², 2²⁰, 5⁻²)
==>(25 1048576 0.04)
. Pełna lista Unicode, którą możesz nadużywać w ten sposób, znajduje się tutaj: docs.perl6.org/language/unicode_texas .