Wskazówki do gry w golfa w MATL

20

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ę!)

Stewie Griffin
źródło
5
Jest to zdecydowanie wielka zaleta, jeśli znasz trochę Matlab / Octave. Kilka sztuczek z Porad do gry w golfa w Matlabie i Poradników do gry w golfa w Octave, również używanych w MATL.
flawr 22.04.16
Sugestia: wygląda na to, że 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ć?
Sundar - Przywróć Monikę

Odpowiedzi:

7

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.

Adnan
źródło
Tylko dla kompletności (i jeśli chcesz dodać do swojej odpowiedzi): każdy poziom schowka Lma również predefiniowaną wartość, ale są one przeznaczone do specjalnych zastosowań (zamiast wspólnych, ogólnych wartości). Na przykład 1Ldaje [1 0](który jest używany jako indeks 1:end), 2Ldaje [0 -1 1](dla 1:-1:end). Ponadto, domyślnie działa li Opobiera 0 danych wejściowych 0oraz 1odpowiednio
Luis Mendo
Nie rozumiem, jak to się przydaje ... Nie mogę po prostu pisać 4?
Cyoce 21.04.16
@Cyoce Przydatnym rozwiązaniem jest unikanie spacji jako separatora. Jeśli chcesz przesunąć 1, a następnie 4, 14nie zrobi. Że trzeba 1 4. Albo 1Ko zapisanie jednego bajtu
Luis Mendo
@LuisMendo ah, rozumiem. Chyba założyłem, że używa tylko 1-cyfrowej metody liczbowej (nie wiem dlaczego)
Cyoce
1
Innym przypadkiem, gdy Kzamiast 4jest przydatny jest: 1-4oznacza: push 1, a następnie push -4; natomiast 1-Koznacza: push 1, odejmij od wszystkiego, co jest poniżej na stosie, a następnie push4
Luis Mendo
5

&Meta-Function (Alternative Wejście / Wyjście Specyfikacja)

Tradycyjnym sposobem określania liczby argumentów wejściowych przekazywanych do funkcji jest użycie $meta-funkcji

2$:     % Two-input version of :

Podobnie, aby określić liczbę argumentów wyjściowych, możesz użyć #meta-funkcji określającej liczbę argumentów wyjściowych,

2#S     % Two-output version of sort

lub jeśli przekażesz liczbę większą niż liczba argumentów wyjściowych zdefiniowanych dla funkcji, tylko dane mod(N, numberOfOutputs) + 1wyjściowe są dostarczane.

4#S     % Get only the second output of sort

Możesz dodatkowo określić tablicę logiczną jako dane wejściowe, #aby pobrać tylko określone argumenty wyjściowe.

TFT#u   % Three output version of unique and discard the second output

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 :jest 1(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ót 2$.

10      % Push 10 to the stack
12      % Push 12 to the stack
2$:     % Create an array: [10, 11, 12] 

Teraz staje się następujący, zapisując bajt !

10 12 &:

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 :

 +- Min-Max range of # of inputs
 |        +----- Alt. Default # of inputs
 |        |
 V        V
1--3 (1 / 2); 1 <--- Possible / Default # of outputs
      ^       
      |       
  Default # of inputs

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

Suever
źródło
1
Ta funkcja została zaproponowana przez @Suever. Pierwotnie &miał oznaczać „zwiększenie liczby wejść o 1 w stosunku do wartości domyślnej”. Jego sugestia okazała się znacznie bardziej przydatna
Luis Mendo
5

Zapoznaj się z prawdomównymi / fałszywymi definicjami MATL-a

Podczas gdy true( T) i false( 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:

if (x)
    disp("x is truthy");
else
    disp("x is falsy");
end

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

` ? 'truthy' } 'falsey' ]DT

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.

  1. 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ść na logicalwartość ( g) lub możesz użyć~~

    F           % Falsy
    T           % Truthy
    0           % Falsy
    1           % Truthy
    2           % Truthy
    -1          % Truthy
    'a'         % Truthy
    ' '         % Truthy (ASCII 32)
    char(0)     % Falsy  (ASCII 0)  
    
  2. 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

    [1, 1, 1]           % Truthy
    [1, 0, 0]           % Falsey
    [1, 1, 1; 1, 1, 1]  % Truthy
    [1, 0, 1; 1, 1, 1]  % Falsey
    'Hello World'       % Truthy
    

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 w all( A), aby utworzyć skalar, możesz usunąć ten ostatni bajt, a Twoja odpowiedź pozostanie poprawna (chyba że dane wyjściowe są, []ponieważ []są, falseale []Atrue).

  • Zapewnienie, że tablica zawiera tylko jedną unikalną wartość : Używa &=zamiast un1=. Jeśli wszystkie wartości w tablicy są równe, rozgłaszane porównanie równości elementów da N x Nmacierz wszystkich. Jeśli wszystkie wartości nie są równe, ta matryca będzie zawierać pewne 0wartości i dlatego będzie uważana za fałsz.

Suever
źródło
4

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:

Domniemane dane wejściowe można wyświetlić w następujący sposób: stos jest nieskończenie rozciągany poniżej dna, to znaczy w pozycjach 0, -1, -2, ... z wartościami, które nie są początkowo zdefiniowane, ale są rozwiązywane w locie za pomocą niejawnych danych wejściowych . Dane wejściowe są zadawane przez użytkownika tylko wtedy, gdy są potrzebne, w kolejności, w jakiej są potrzebne. Jeśli wymaganych jest kilka danych wejściowych w tym samym czasie, stosują się one do normalnej kolejności stosów, to znaczy dane wejściowe najgłębsze w stosie (rozszerzonym) są wprowadzane jako pierwsze.

wada
źródło
2
Domniemane dane wejściowe to funkcja sugerowana przez @flawr
Luisa Mendo
6
@flawr musi być naprawdę sprytnym facetem. : D
wada
3

Tablice logiczne mogą być często używane jako tablice numeryczne

Często możesz używać TFnotacji „ ” zamiast literałów tablicowych zer i jedynek. Na przykład FTFjest taki sam, jak [0,1,0]tylko, że FTFprodukuje logicalwartości, nie doublewartości. Zwykle nie stanowi to problemu, ponieważ każda operacja arytmetyczna traktuje wartości logiczne jak liczby. Na przykład FTFQdaje [1,2,1]( Qto „wzrost o 1”).

W niektórych przypadkach konwersja liczby na binarną może być krótsza. Na przykład [1,0,1], TFTi 5Bsą takie same; ponownie z ostrożnością, że te dwa ostatnie są logicalwartościami.


Przypadek, w którym różnica między TF(logicznym) a [1 0](numerycznym) ma znaczenie, gdy jest stosowany jako indeks. Tablica typu logicalużywana jako indeks oznacza: wybierz elementy odpowiadające T, odrzuć te odpowiadające F. Tak [10 20]TF)produkuje 10(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).

Luis Mendo
źródło
3

Do pętli o rozmiarze n-1

Rozważyć wymianę

tnq:"...

z

td"...

aby zaoszczędzić do całego bajtu lub więcej .

Sanchises
źródło
@Luis true! Pomyślałem, że może być potrzebny oryginalny wektor, który jest zapętlony, ale nie jest to możliwe w pierwszym podejściu. Usunie tę uwagę.
Sanchises,
Ale niekoniecznie oszczędzasz 1 bajt; zapisujesz 1 lub 2 w zależności od tego, czy potrzebujesz @/ X@w pętli, czy nie. Może możesz po prostu powiedzieć „oszczędzać bajty”
Luis Mendo,
3

Przenieś rzeczy od pętli do pętli, aby wykorzystać niejawny koniec

endInstrukcje 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 ):

  • Kod zapętla się od 1do N.
  • Dla każdej z tych liczb oblicza czynniki pierwsze i określa, ile razy 5jest obecnych.
  • Odpowiedzią jest skumulowana liczba 5wyświetleń (działa to, ponieważ dla każdego 5jest co najmniej jeden 2).

Pierwszym pomysłem było :"@Yf5=]vs(zauważ, że po pętli są instrukcje):

:      % Range from 1 to implicit input
"      % For each number in that vector
  @    %   Push that number
  Yf   %   Vector of prime factors (with repetitions)
  5=   %   True for entries that equal `5`, and `false` for the rest
]      % End for
v      % Concatenate all vectors as a column vector
s      % Sum. Implicitly display

Ponieważ vdomyślnie łączy całą zawartość stosu, można ją przenieść do pętli. A ponieważ dodawanie jest asocjacyjne, smożna je również przenosić. Pozostawia to ]na końcu kodu, dlatego można go pominąć :"@Yf5=vs:

:      % Range from 1 to implicit input
"      % For each number in that vector
  @    %   Push that number
  Yf   %   Vector of prime factors (with repetitions)
  5=   %   True for entries that equal `5`, and `false` for the rest
  v    % Concatenate all vectors so far as a column vector
  s    % Sum. Inplicitly end loop and display
Luis Mendo
źródło
nie znam ani grosza tego hieroglificznego języka pisanego, ale zarezerwuję większą część mojego czasu na studiowanie go przez następne trzy miesiące.
Abr001am
@ Agawa001 :-) Przekonasz się, że jest dość podobny do Matlaba. Możesz również zapytać lub skomentować tutaj
Luis Mendo
3

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 .

Luis Mendo
źródło
2

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 reshapefunkcję MATLAB , która w MATL odpowiada e. Fragmenty kodu reshape([10 20 30 40 50 60], 2, 3)i reshape([10 20 30 40 50 60], 2, [])odpowiednio oznaczają „przekształć wektor wiersza [10 20 30 40 50 60w macierz 2 × 3” lub „w macierz 2-rzędową z tyloma kolumnami, ile potrzeba”. Zatem w obu przypadkach wynikiem jest tablica 2D

10    30    50
20    40    60

Coś w rodzaju reshape([10 20 30 40 50 60], 2, 2)lub reshape([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ć

10 30
20 40 

i

10 60
20  0
30  0
40  0
50  0

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).

Luis Mendo
źródło
1

Uzyskaj indeks pierwszego niezerowego elementu, jeśli taki istnieje

fFunkcja daje wskaźników wszystkich niezerowych elementów macierzy. Często chcesz indeks pierwszego niezerowego elementu. To byłoby f1): zastosuj fi wybierz pierwszy element. Ale jeśli oryginalna tablica nie zawiera żadnej niezerowej wartości f, 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ą ifoddziału później f, ale jest to kosztowne bajtowo. Lepszym sposobem jest fX<zastosowanie funkcji minimalnej X<na wyjściu f. 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 .

Luis Mendo
źródło
1

Wygeneruj zakres tak długo, jak dana tablica

TL; WR : użyj fzamiast, n:jeśli tablica zawiera tylko niezerowe elementy.


Często zdarza się, że trzeba wygenerować tablicę, w [1 2 ... L]której Ljest liczba elementów danej tablicy. Standardowy sposób to zrobić n:. Na przykład kod tn:*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 .

Luis Mendo
źródło
1

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 hi v), a także gotowych literałów unikać używania spacji jako separatory porównanie [2 4], 2 4hi 2Kh, z których wszystkie zdefiniować tablicę [2 4]. Podobnie 2K1vz 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 KMają swoje zwykłe znaczenia 0, ...,4
  • A, ..., Eznaczy 5...9
  • X znaczy 10
  • a, ... dznaczy -1, ...,-4
  • Ji Goznacza 1ji-1j
  • P znaczy pi
  • Y znaczy inf
  • Nśrodki NaN.

Różnice w ciągach znaków i kolejne

W przypadku większych liczb dpomocne 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ż dwykorzystuje punkty kodowe znaków do obliczania różnic. Przykład .

Luis Mendo
źródło