Niedawno rozpocząłem jedno wyzwanie golfowe i wydaje się, że zwycięzcą jest GolfScript (niespodzianka, niespodzianka!). Co ciekawe, był jeszcze jeden bardzo silny konkurent, który miał wszelkie szanse wygrać z GolfScript. Nazywa się APL. Widzę tu wiele odpowiedzi napisanych w APL. Wygląda na to, że ten język jest dość wydajny do gry w golfa kodowego, więc postanowiłem poprosić o wszelkie wskazówki dotyczące gry w golfa, które znasz dla programów APL. Opublikuj kilka przykładów kodu. Zwykle bardzo interesujący jest widok języka w akcji.
Pociągi
źródło
Sztuczki do radzenia sobie z pociągami
/
i⌿
w pociągachPrzy korzystaniu z pociągów może chcesz użyć redukcji
f/
takich jak sumy+/
, a nawet zmniejszenie replikacji//
. Jeśli jednak twój pociąg ma więcej części po lewej stronie redukcji, potrzebujesz nawiasów, aby utworzyć szczyt. Oto kilka sztuczek, aby zaoszczędzić bajty.Użyj
1∊
zamiast tablic monadycznych∨/
lub∨⌿
na tablicach boolowskichZadanie: Biorąc pod uwagę dwa ciągi A i B o równej długości, zwróć 2, jeśli dowolne odpowiadające znaki A i B są równe, w przeciwnym razie 0. Np
A←'abc'
iB←'def'
daje0
aA←'abc'
iB←'dec'
daje2
.Rozwiązanie dfn może być,
A{2×∨/⍺=⍵}B
ale chcesz je skrócić, przechodząc milczenie.A(2×∨/=)B
nie zadziała, ponieważ zasady formowania pociągów parsują to tak, jak2 (× ∨/ =)
chcesz2 × (∨/=)
.Zauważ, że
∨/
lub∨⌿
na wektorze boolowskim (∨/,
lub w∨⌿,
przypadku tablic wyższej rangi) pyta, czy jest jakikolwiek 1, tzn. Czy1∊
możemy napisać nasz pociąg jako2×1∊=
.Zwróć uwagę, że
∊
zachowuje właściwy argument, więc nie można go użyć do zmniejszenia każdego wiersza lub kolumny osobno.Użyj
1⊥
zamiast monadycznego+/
lub+⌿
Zadanie: Biorąc pod uwagę listę list L i indeks N, zwróć trzykrotnie sumę N-tej listy. Np.
L←(3 1 4)(2 7)
IN←1
daje24
.Rozwiązanie dfn może być,
N{3×+/⍺⊃⍵}L
ale chcesz je skrócić, przechodząc milczenie.N(3×+/⊃)L
nie zadziała, ponieważ zasady formowania pociągów parsują to tak, jak3(× +/ ⊃)
chcesz3 × (+/⊃)
.Zauważ, że ocena listy liczb w jednostkowej (podstawa-1) jest równoważna zsumowaniem listy, ponieważ ∑ { a , b , c , d } = a + b + c + d = ( a × 1³) + ( b × 1² ) + ( c × 1¹) + ( d × 1⁰). Dlatego
+/a b c d
jest taki sam jak1⊥a b c d
i możemy napisać nasz pociąg jako3×1⊥⊃
.Zauważ, że w argumentach wyższej rangi
1⊥
jest to równoważne z+⌿
.Użyj
f.g
zamiastf/g
z argumentami skalarnymi i / lub wektorowymiZadanie: Biorąc pod uwagę listę L i liczbę N, zwróć zakres 1 dokładnie liczbę resztek minimalnego podziału, gdy elementy L zostaną podzielone przez NEg
L←31 41 59
iN←7
daje1 2 3
.Rozwiązanie dfn może być,
N{⍳⌊/⍺|⍵}L
ale chcesz je skrócić, przechodząc milczenie.N(⍳⌊/|)L
nie zadziała, ponieważ zasady formowania pociągów parsują to tak, jak⍳ (⌊/) |
chcesz⍳ (⌊/|)
.Wewnętrzny iloczyn
A f.g B
dwóch funkcji skalarnych, gdy argumentami są skalary i / lub wektory, jest taki sam,f/ A g B
ponieważ oba są(A[1] g B[1]) f (A[2] g B[2]) f (A[3] g B[3])
itp., Więc możemy napisać nasz ciąg jako⍳⌊.|
.Zauważ, że to nie działa w przypadku tablic wyższego rzędu.
Użyj
∊⊆
zamiast/
z logicznymi argumentami lewej i prostej wektorowej prawejZadanie: biorąc pod uwagę listę L i liczbę N, przefiltruj listę, aby pozostały tylko liczby większe niż N. Np.
L←3 1 4
IN←1
daje3 4
.Rozwiązanie dfn może być,
N{(⍺<⍵)/⍵}L
ale chcesz je skrócić, przechodząc milczenie.N(</⊢)L
nie zadziała, ponieważ reguły wiązania to przeanalizują, ponieważ(</) ⊢
chcesz/
być replikacją funkcji, a nie operatorem zmniejszania .Dyadic
⊆
z logicznym lewym argumentem dzieli prawy argument zgodnie z przebiegiem 1s w lewym argumencie, usuwając elementy wskazane przez 0s. To jest prawie to, czego chcemy, z wyjątkiem niechcianego partycjonowania. Możemy jednak pozbyć się partycjonowania, stosując monadic∊
. W ten sposób{(⍺<⍵)/⍵}
możemy się stać{∊(⍺<⍵)⊆⍵}
i w ten sposób możemy napisać nasz pociąg jako∊<⊆⊢
.Zauważ, że to nie działa w przypadku tablic wyższego rzędu.
Użyj
0⊥
zamiast⊢/
lub⊢⌿
z argumentami numerycznymiZadanie: Biorąc pod uwagę listę L i liczbę N, pomnóż N przez najbardziej prawy element LEg
L←3 1 4
iN←2
daje8
.Rozwiązanie dfn może być,
N{⍺×⊢/⍵}L
ale chcesz je skrócić, przechodząc milczenie.N(⊣×⊢/⊢)L
nie zadziała, ponieważ zasady formowania pociągów parsują to tak, jak⊣ (× ⊢/ ⊢)
chcesz⊣ × (⊢/⊢)
.Zauważ, że
0⊥
na tablicy liczbowej jest to samo⊢⌿
, więc możemy napisać nasz pociąg jako⊣×0⊥⊢
.Zauważ, że wybiera to ostatnią główną komórkę tablic wyższego rzędu.
źródło
Służy
⊥
do łączenia mnożenia z dodawaniemZałożenia:
a
ib
są warunkami, które nie wymagają dalszych nawiasów, gdy są używane jako lewy argumentC
jest wyrażeniem, które może wymagać nawiasów, gdy jest używane jako lewy argumenta
b
C
oceniać na skalary numeryczneźródło
Liczby zespolone
Często pomijane, stwarzają wspaniałe możliwości skrócenia wyrażeń dotyczących siatek, labiryntów, fraktali lub geometrii.
źródło
Indeksowanie długości wektora modulo
⊃i⌽a
jest często krótszy niż naiwny⊃a[(≢a)|i]
luba⊃⍨i|⍨≢a
(gdziea
jest wektorem ii
jest liczbą całkowitą i⎕io
wynosi 0)użyteczną odmianą tego (dzięki EriktheOutgolfer za wskazanie) jest:
I↑Y⌽⍨I×X
gdzieY
jest konkatenacja niektórychI
wektorów długości iX
jest indeksem tego, który chcemy wybrać, na przykład:3↑'JanFeb...Dec'⌽⍨3×month
źródło
Funkcje stałe
=⍨
i≠⍨
dzięki ngn.Czasami potrzebujesz tylko jednej wartości dla każdego elementu listy. Chociaż możesz ulec pokusie użycia
{value}¨
, jest on krótszy,value⊣¨
ale w przypadku niektórych typowych wartości możesz stać się jeszcze krótszy (używając⎕IO←0
):¯1
s z⍬⍸list
0
s z⍬⍳list
1
s z⍬⍷list
Pamiętaj, że działają one tylko na listach (choć mogą być zagnieżdżone). W przypadku tablic wyższego rzędu możesz użyć następujących elementów, aby uzyskać wszystkie 0 i wszystkie 1:
1
s z=⍨
0
s z≠⍨
Jeśli ustawisz
⎕ML←0
, wszystkie liczby mogą być przekształcone w zera (jak gdyby0×
) za pomocą:∊
Jeśli potrzebujesz tylko jednego numeru, możesz użyć monadycznego,
≡
aby uzyskać 1 lub 0 zamiast używania1⊣
lub0⊣
.źródło
⊣\
⊣
i⊢
ze/
i⌿
zasługa stanowisko własne.Posługiwać się
⍨
Unikaj nawiasów
⍨
(Dojazdy) może zaoszczędzić bajty, unikając nawiasów. Ilekroć masz funkcję, w której lewy argument musi być nawiasowany, a prawy argument nie, możesz zapisać bajt, np .(A<B)÷C
→C÷⍨A<B
.Podwójne tablice
Aby dołączyć kopię tablicy do jej końca, użyj
,⍨A
lub⍪⍨A
.Podwójne liczby
Zamiast
2∘×
podwójnego możesz użyć,+⍨
ponieważ dodaje on argument do siebie:1+2∘×
→1++⍨
.Liczby kwadratowe
Zamiast
2*⍨Y
kwadratu można użyć,×⍨Y
ponieważ mnoży argument z samym sobą:2*⍨A+B
→×⍨A+B
.Losowa permutacja
?⍨N
da ci losową permutację długościN
.Samoklasyfikuj się
Znajdź wskaźniki pierwszego wystąpienia każdej głównej komórki za pomocą
⍳⍨A
Policz końcowe 1s w wektorze boolowskim
Zamiast
+/∧\⌽B
policzyć, ile końcowych jedynek jest w środkuN
, możesz użyć⊥⍨
.Odwrotna kompozycja
A f∘g B
jestA f g B
, ale jeśli chcesz(g A) f B
, użyjf⍨∘g⍨
.Odwróć redukcję
f/ a1 a2 a3
jesta1 f (a2 f a3)
. Jeśli chcesz(a1 f a2) f a3
, użyjf⍨/⌽
.Skanowanie do tyłu
f\ A B C
jestA (A f B) (A f (B f C))
.f⍨/∘⌽¨,\ A B C
jestA (A f B) ((A f B) f C)
.f⍨\⌽ A B C
jest((A f B) f C) (B f C) C
.⌽f/∘⌽¨,\⌽ A B C
. jest(A f (B f C)) (B f C) C
.źródło
Wymień znaki w ciągu bez
⍳≢
Zadanie: Biorąc pod uwagę dwa łańcuchy, S i T, wymień wskaźniki ich konkatenacji. Np.
S←'abcd'
IT←'xyz'
daje1 2 3 4 5 6 7
.Rozwiązanie dfn może być,
S{⍳≢⍺,⍵}T
ale chcesz je skrócić, przechodząc milczenie.⍳≢,
nie zadziała, ponieważ reguły analizy składni parsują to tak, jak(⍳)≢(,)
chcesz(⍳≢),
.Dyadic
⍋
z pustym lewym argumentem ocenia proste tablice znaków zgodnie z ich bieżącą kolejnością, która jest taka sama jak⍳≢
. Tak{⍳≢⍺,⍵}
może się stać{⍬⍋⍺,⍵}
, abyśmy mogli napisać nasz pociąg jako⍬⍋,
.Pamiętaj, że nie działa to w przypadku tablic numerycznych lub mieszanych.
źródło