MATL to język golfa stworzony przez Luisa Mendo . MATL okazał się bardzo konkurencyjny, często pokonując zgłoszenia w innych językach golfowych, takich jak Pyth, CJam i Jelly.
Jakie są przydatne wskazówki dotyczące gry w golfa w MATL? (Jak zawsze, jedna wskazówka na odpowiedź, proszę!)
- Dla przypomnienia, MATL można przetestować online tutaj .
- Dokumentację można znaleźć na Github
accumarray
(XQ
) może być dość potężny (być może nawet większy niż w MATLAB / Octave, ponieważ te uchwyty funkcji długości mają przydatne kody numeryczne), ale nie znam go wystarczająco dobrze, aby to zilustrować dobrymi przykładami. Jeśli rzeczywiście jest to przydatne, czy ktoś mógłby stworzyć odpowiedź z pomysłami, jak z niego korzystać?Odpowiedzi:
Znać predefiniowane literały
Chociaż niektóre z nich przechowują informacje podczas kopiowania do schowka, wszystkie mają wstępnie zdefiniowaną wartość.
F
, wypycha 0 (faktycznie False )T
, wypycha 1 (faktycznie Prawda )H
, wypycha 2 (predefiniowana wartość schowka)I
, wypycha 3 (predefiniowana wartość schowka)K
, wypycha 4 (predefiniowana wartość schowka)J
, przesuwa 0 + 1j (predefiniowana wartość schowka)Nie jestem jednak pewien, czy objąłem wszystkie predefiniowane wartości.
źródło
L
ma również predefiniowaną wartość, ale są one przeznaczone do specjalnych zastosowań (zamiast wspólnych, ogólnych wartości). Na przykład1L
daje[1 0]
(który jest używany jako indeks1:end
),2L
daje[0 -1 1]
(dla1:-1:end
). Ponadto, domyślnie działal
iO
pobiera 0 danych wejściowych0
oraz1
odpowiednio4
?1
, a następnie4
,14
nie zrobi. Że trzeba1 4
. Albo1K
o zapisanie jednego bajtuK
zamiast4
jest przydatny jest:1-4
oznacza: push1
, a następnie push-4
; natomiast1-K
oznacza: push1
, odejmij od wszystkiego, co jest poniżej na stosie, a następnie push4
&
Meta-Function (Alternative Wejście / Wyjście Specyfikacja)Tradycyjnym sposobem określania liczby argumentów wejściowych przekazywanych do funkcji jest użycie
$
meta-funkcjiPodobnie, aby określić liczbę argumentów wyjściowych, możesz użyć
#
meta-funkcji określającej liczbę argumentów wyjściowych,lub jeśli przekażesz liczbę większą niż liczba argumentów wyjściowych zdefiniowanych dla funkcji, tylko dane
mod(N, numberOfOutputs) + 1
wyjściowe są dostarczane.Możesz dodatkowo określić tablicę logiczną jako dane wejściowe,
#
aby pobrać tylko określone argumenty wyjściowe.Wszystkie te dane wejściowe / wyjściowe są przydatne, ale bardzo szybko zwiększają liczbę bajtów. Aby temu zaradzić, MATL wprowadził
&
meta-funkcję w wersji 17.0.0 . Ta&
meta-funkcja działa jako skrót do określonej specyfikacji wejścia lub wyjścia dla funkcji. Zobaczmy, co to znaczy.W powyższym przykładzie chcieliśmy użyć wersji z dwoma wejściami
:
(tworzy wektor wartości o równych odstępach). Chociaż domyślną liczbą argumentów wejściowych:
jest1
(tworzy tablicę z[1...N]
), bardzo często użytkownik chce określić wartość początkową zakresu, który wymaga drugiego wejścia. Dlatego:
zdefiniowaliśmy&
skrót2$
.Teraz staje się następujący, zapisując bajt !
Jak możemy ustalić, jaka jest alternatywna liczba argumentów?
&
Przekłada się na specyfikację wejścia / wyjścia, która jest specyficzna dla funkcji, dzięki czemu optymalizujemy oszczędność bajtów.Sekcja argumentów wejścia / wyjścia w opisie pomocy dla każdej funkcji została zaktualizowana, aby wskazać, jaka jest ta alternatywna liczba wejść / wyjść (jeśli występuje). Możliwa liczba argumentów wejściowych lub wyjściowych jest wyświetlana jako zakres, a wartości domyślne dla każdego z nich są wyświetlane w nawiasach. Specyfikacja wejścia / wyjścia, którą można zastąpić,
&
jest pokazana po/
znaku w nawiasach.Oto sekcja argumentów wejścia / wyjścia w opisie pomocy dla
:
Jak ustaliłeś, co
&
oznacza dla każdej funkcji?Bardzo ostrożnie. Korzystając z interfejsu API StackExchange , byliśmy w stanie pobrać wszystkie odpowiedzi MATL, które były kiedykolwiek używane w wyzwaniu PPCG. Analizując każdą z odpowiedzi, byliśmy w stanie określić częstotliwość, z jaką każda specyfikacja wejścia / wyjścia była używana dla każdej funkcji. Korzystając z tych informacji, byliśmy w stanie obiektywnie zidentyfikować specyfikację wejścia / wyjścia, którą
&
meta-funkcja powinna reprezentować dla każdej funkcji. Czasami nie było wyraźnego zwycięzcy, więc wiele funkcji obecnie nie zostało&
zdefiniowanych.Oto skrypt, którego użyliśmy (niestety jest napisany w MATLAB, a nie MATL).
I tu jest przykładem histogramu z
$
/#
użytkowaniaźródło
&
miał oznaczać „zwiększenie liczby wejść o 1 w stosunku do wartości domyślnej”. Jego sugestia okazała się znacznie bardziej przydatnaZapoznaj się z prawdomównymi / fałszywymi definicjami MATL-a
Podczas gdy
true
(T
) ifalse
(F
) wyraźnie reprezentują odpowiednio wynik prawda i fałsz, szeroko uzgodniona definicja prawda / fałsz daje nam nieco większą elastyczność w MATL.Definicja stwierdza:
Możemy więc napisać szybki test prawdy / fałszu MATL, który przejdzie przez wszystkie dane wejściowe i wyświetli, czy zostały uznane za prawdziwe lub fałszywe
Oto wersja online.
Co to oznacza w MATL
To, co faktycznie przekłada się na MATLAB (a zatem na MATLAB i Octave), polega na tym, że warunek jest uważany za prawdziwy, jeśli jest niepusty, a rzeczywiste składowe wszystkich jego wartości są niezerowe . Należy podkreślić dwie części.
Niezerowe : Oznacza to dokładnie, że nie równa się zero (
==
). Obejmuje to liczby dodatnie, liczby ujemne, znaki niepuste itp. Możesz łatwo sprawdzić, konwertując daną wartość nalogical
wartość (g
) lub możesz użyć~~
Wszystkie wartości : zazwyczaj myślimy o skalarach jako o prawdzie lub fałszu, ale w MATL możemy oceniać skalary, wektory rzędów, wektory kolumn, a nawet macierze wielowymiarowe i są one uważane za prawdziwe, jeśli tylko każda wartość jest niezerowe (jak zdefiniowano powyżej), w przeciwnym razie są fałszem. Oto kilka przykładów do zademonstrowania
Przypadek z jedną krawędzią, jak wspomniano powyżej, to pusta tablica
[]
, którą zawsze uważa się za fałsz ( przykład )Jak mogę to lepiej wykorzystać do gry w golfa?
Jeśli wyzwanie po prostu wspomina, że twoja twórczość powinna być zgodna z prawdą lub fałszem, możesz prawdopodobnie wykorzystać powyższą definicję, aby odciąć kilka bajtów od odpowiedzi. Aby uniknąć nieporozumień, zaleca się dołączenie do odpowiedzi linku do internetowego testu prawdy / fałszu powyżej, aby pomóc wyjaśnić, jak działają wartości prawdy / fałszu MATL.
Kilka konkretnych przykładów:
Odpowiedź kończąca się na
A
. Jeśli wyzwanie wymaga podania danych zgodnych z prawdą lub fałszem, a odpowiedź zakończysz wall
(A
), aby utworzyć skalar, możesz usunąć ten ostatni bajt, a Twoja odpowiedź pozostanie poprawna (chyba że dane wyjściowe są,[]
ponieważ[]
są,false
ale[]A
sątrue
).Zapewnienie, że tablica zawiera tylko jedną unikalną wartość : Używa
&=
zamiastun1=
. Jeśli wszystkie wartości w tablicy są równe, rozgłaszane porównanie równości elementów daN x N
macierz wszystkich. Jeśli wszystkie wartości nie są równe, ta matryca będzie zawierać pewne0
wartości i dlatego będzie uważana za fałsz.źródło
Implikowane wejście
Większość funkcji akceptuje pewną liczbę danych wejściowych. Te dane wejściowe są pobierane z góry stosu. Jeśli góra stosu nie zawiera wystarczającej liczby argumentów, narysuje pozostały argument z danych wejściowych. (Patrz sekcja 7.3 w dokumentacji) Chciałbym zacytować oryginalne wyjaśnienie:
źródło
Tablice logiczne mogą być często używane jako tablice numeryczne
Często możesz używać
TF
notacji „ ” zamiast literałów tablicowych zer i jedynek. Na przykładFTF
jest taki sam, jak[0,1,0]
tylko, żeFTF
produkujelogical
wartości, niedouble
wartości. Zwykle nie stanowi to problemu, ponieważ każda operacja arytmetyczna traktuje wartości logiczne jak liczby. Na przykładFTFQ
daje[1,2,1]
(Q
to „wzrost o 1”).W niektórych przypadkach konwersja liczby na binarną może być krótsza. Na przykład
[1,0,1]
,TFT
i5B
są takie same; ponownie z ostrożnością, że te dwa ostatnie sąlogical
wartościami.Przypadek, w którym różnica między
TF
(logicznym) a[1 0]
(numerycznym) ma znaczenie, gdy jest stosowany jako indeks. Tablica typulogical
używana jako indeks oznacza: wybierz elementy odpowiadająceT
, odrzuć te odpowiadająceF
. Tak[10 20]TF)
produkuje10
(wybierz pierwszy element), podczas gdy[10 20][1 0])
produkuje[10 20]
(indeks[1 0]
ma interpretację1:end
, to znaczy, wybierz wszystkie elementy tablicy).źródło
Do pętli o rozmiarze n-1
Rozważyć wymianę
z
aby zaoszczędzić do całego bajtu lub więcej .
źródło
@
/X@
w pętli, czy nie. Może możesz po prostu powiedzieć „oszczędzać bajty”Przenieś rzeczy od pętli do pętli, aby wykorzystać niejawny koniec
end
Instrukcje pętli]
, można pominąć, jeśli po nich nie ma kodu. Są one domyślnie wypełniane przez parser MATL.Jeśli więc możesz przenieść rzeczy z pętli do pętli, możesz zapisać finał
]
.Jako konkretny przykład poniższy kod pokazuje, ile zera jest w silni liczby
N
(zobacz to tutaj ):1
doN
.5
jest obecnych.5
wyświetleń (działa to, ponieważ dla każdego5
jest co najmniej jeden2
).Pierwszym pomysłem było
:"@Yf5=]vs
(zauważ, że po pętli są instrukcje):Ponieważ
v
domyślnie łączy całą zawartość stosu, można ją przenieść do pętli. A ponieważ dodawanie jest asocjacyjne,s
można je również przenosić. Pozostawia to]
na końcu kodu, dlatego można go pominąć:"@Yf5=vs
:źródło
Krótszy sposób zdefiniowania pustej tablicy numerycznej, jeśli stos jest pusty
Aby wypchnąć pustą tablicę numeryczną, której zwykle używasz
[]
. Jeśli jednak stos jest pusty, można zapisać bajt za pomocąv
. Ta funkcja domyślnie łączy całą zawartość stosu pionowo, więc jeśli stos jest pusty, tworzy pustą tablicę.Możesz zobaczyć to w akcji na przykład tutaj .
źródło
Niektóre funkcje są rozszerzone w porównaniu z MATLAB lub Octave
Jeśli pochodzisz z MATLAB lub Octave, przekonasz się, że wiele funkcji MATL jest podobnych do funkcji w tych językach. Ale w wielu z nich funkcjonalność została rozszerzona.
Jako przykład rozważmy
reshape
funkcję MATLAB , która w MATL odpowiadae
. Fragmenty kodureshape([10 20 30 40 50 60], 2, 3)
ireshape([10 20 30 40 50 60], 2, [])
odpowiednio oznaczają „przekształć wektor wiersza[10 20 30 40 50 60
w macierz 2 × 3” lub „w macierz 2-rzędową z tyloma kolumnami, ile potrzeba”. Zatem w obu przypadkach wynikiem jest tablica 2DCoś w rodzaju
reshape([10 20 30 40 50 60], 2, 2)
lubreshape([10 20 30 40 50 60], 5, [])
dałoby błąd z powodu niezgodnych rozmiarów. Jednak MATL usunie elementy w pierwszym przypadku ( wypróbuj online! ) Lub wypełni je zerami w drugim ( wypróbuj online! ), Aby odpowiednio wygenerowaći
Inne funkcje, które mają rozszerzoną funkcjonalność w porównaniu z odpowiednikami MATLAB, to (niewyczerpująca lista)
S
(sort
),Yb
(strsplit
),m
(ismember
),h
(horzcat
),v
(vertcat
),Zd
(gcd
),Zm
(lcm
),YS
(circshift
),YA
(dec2base
),ZA
(base2dec
),Z"
(blanks
).źródło
Uzyskaj indeks pierwszego niezerowego elementu, jeśli taki istnieje
f
Funkcja daje wskaźników wszystkich niezerowych elementów macierzy. Często chcesz indeks pierwszego niezerowego elementu. To byłobyf1)
: zastosujf
i wybierz pierwszy element. Ale jeśli oryginalna tablica nie zawiera żadnej niezerowej wartościf
, wyświetli pustą tablicę ([]
), a próba wybrania jej pierwszego elementu spowoduje błąd.Częstym, bardziej niezawodnym wymogiem jest uzyskanie indeksu pierwszego elementu, jeśli jest co najmniej jeden , i w
[]
przeciwnym razie. Można to zrobić za pomocąif
oddziału późniejf
, ale jest to kosztowne bajtowo. Lepszym sposobem jestfX<
zastosowanie funkcji minimalnejX<
na wyjściuf
.X<
zwraca pustą tablicę, gdy jej wejściem jest pusta tablica.Wypróbuj online! (Zauważ, że pusta tablica wcale nie jest wyświetlana). Lub zobacz przykład tego w pracy tutaj .
źródło
Wygeneruj zakres tak długo, jak dana tablica
TL; WR : użyj
f
zamiast,n:
jeśli tablica zawiera tylko niezerowe elementy.Często zdarza się, że trzeba wygenerować tablicę, w
[1 2 ... L]
którejL
jest liczba elementów danej tablicy. Standardowy sposób to zrobićn:
. Na przykład kodtn:*
przyjmuje wektor numeryczny jako dane wejściowe i oblicza każdy wpis pomnożony przez jego indeks.Jeśli dana tablica ma gwarantować, że zawiera tylko niezerowe wpisy (na przykład jest utworzona z dodatnich liczb całkowitych lub jest łańcuchem ze znakami do wydrukowania),
n:
można ją zastąpićf
, co daje tablicę ze wskaźnikami niezerowych wpisów. Tak więc powyższy kod staje siętf*
, co oszczędza 1 bajt.Kilka bardziej szczegółowych przykładów: 1 , 2 , 3 .
źródło
Skuteczne definiowanie literałów tablic numerycznych
Oto kilka sposobów zapisywania bajtów podczas definiowania literałów tablic numerycznych. Podano linki do przykładowych odpowiedzi, które ich używają. Zostały one uzyskane przy użyciu skryptu analitycznego utworzonego przez @Suever .
Łączenie i predefiniowane literały
Dla tablic z niewielkich ilościach można czasem użyć konkatenacji (funkcje
h
iv
), a także gotowych literałów unikać używania spacji jako separatory porównanie[2 4]
,2 4h
i2Kh
, z których wszystkie zdefiniować tablicę[2 4]
. Podobnie2K1v
z pustym stosem definiuje[2; 4; 1]
. Przykład .Litery w literałach tablic numerycznych
W przypadku nieco większych liczb można zaoszczędzić miejsca wykorzystując fakt, że niektóre litery mają znaczenie liczbowe w literałach tablicowych. Zamiast tego
[3 5 2 7;-4 10 12 5]
możesz użyć[IAHC;dX12A]
. Przykład .W szczególności w obrębie literałów tablicowych
O
,l
,H
I
K
Mają swoje zwykłe znaczenia0
, ...,4
A
, ...,E
znaczy5
...9
X
znaczy10
a
, ...d
znaczy-1
, ...,-4
J
iG
oznacza1j
i-1j
P
znaczypi
Y
znaczyinf
N
środkiNaN
.Różnice w ciągach znaków i kolejne
W przypadku większych liczb
d
pomocne może być zdefiniowanie ciągu i obliczenie jego kolejnych różnic (z ): zamiast[20 10 35 -6]
możesz użyć'!5?b\'d
. Działa to, ponieważd
wykorzystuje punkty kodowe znaków do obliczania różnic. Przykład .źródło