MATL ist eine von Luis Mendo entwickelte Golfsprache . MATL hat sich als äußerst wettbewerbsfähig erwiesen und Einsendungen in anderen Golfsprachen wie Pyth, CJam und Jelly oft geschlagen .
Was sind einige nützliche Tipps zum Golfen in MATL? (Bitte wie immer einen Tipp pro Antwort!)
- MATL kann hier online getestet werden .
- Dokumentation finden Sie auf Github
accumarray
(XQ
) ziemlich mächtig sein kann (möglicherweise sogar mehr als in MATLAB / Octave, da diese Längenfunktionsgriffe praktische numerische Codes haben), aber ich kenne es nicht gut genug, um es mit guten Beispielen zu veranschaulichen. Wenn es tatsächlich nützlich ist, könnte jemand eine Antwort mit Ideen zur Verwendung erstellen?Antworten:
Kennen Sie die vordefinierten Literale
Einige von ihnen behalten zwar Informationen bei, wenn sie in die Zwischenablage kopiert werden, haben jedoch alle einen vordefinierten Wert.
F
, drückt 0 (eigentlich Falsch )T
, drückt 1 (tatsächlich wahr )H
, drückt 2 (vordefinierter Wert der Zwischenablage)I
, drückt 3 (vordefinierter Wert der Zwischenablage)K
, drückt 4 (vordefinierter Zwischenablage-Wert)J
, drückt 0 + 1j (vordefinierter Wert der Zwischenablage)Ich bin mir nicht sicher, ob ich alle vordefinierten Werte abgedeckt habe.
quelle
L
hat auch einen vordefinierten Wert, aber sie sind für spezielle Zwecke gedacht (und nicht für allgemeine Werte). Zum Beispiel1L
gibt[1 0]
(der als Index verwendet wird1:end
),2L
gibt[0 -1 1]
(für1:-1:end
). Auch Funktionenl
undO
nehmen 0 Eingänge standardmäßig aktiviert und produziert0
und1
jeweils4
?1
, dann4
geht14
das nicht. Du würdest brauchen1 4
. Oder1K
um ein Byte zu speichernK
anstelle von4
praktisch ist, ist:1-4
bedeutet: drücken1
, dann drücken-4
; während1-K
bedeutet: drücken1
, subtrahieren von was auch immer unten im Stapel ist, dann drücken4
Das
&
Meta-Funktion (Alternative Eingabe- / Ausgabespezifikation)Die traditionelle Art, die Anzahl der Eingabeargumente anzugeben, die an eine Funktion übergeben werden sollen, ist die Verwendung der
$
Meta-FunktionUm die Anzahl der Ausgabeargumente festzulegen, können Sie auch die
#
Meta-Funktion verwenden, die entweder die Anzahl der Ausgabeargumente angibt.Übergeben Sie eine Zahl, die größer ist als die Anzahl der für eine Funktion definierten Ausgabeargumente, wird nur die
mod(N, numberOfOutputs) + 1
Ausgabe bereitgestellt.Sie können zusätzlich ein logisches Array als Eingabe angeben
#
, um nur bestimmte Ausgabeargumente abzurufen.Alle diese Eingabe- / Ausgabespezifikationen sind praktisch , erhöhen jedoch die Bytezahl sehr schnell. Um dies zu bewältigen, hat MATL die
&
Meta-Funktion in Version 17.0.0 eingeführt . Dies&
Metafunktion fungiert als Verknüpfung für eine bestimmte Eingabe- oder Ausgabespezifikation für eine Funktion. Mal sehen, was das bedeutet.In unserem obigen Beispiel wollten wir die Version von mit zwei Eingängen verwenden
:
(erstellt einen Vektor mit Werten mit gleichem Abstand). Während die Standardanzahl von Eingangsargumente:
IS1
(ein Array aus erzeugt[1...N]
), ist es sehr üblich , dass ein Benutzer den Startwert des Bereichs spezifizieren möchte , die den zweiten Eingang erfordert. Also für:
haben wir definiert&
für eine Verknüpfung zu sein2$
.Jetzt wird folgendes, ein Byte speichern !
Wie können wir die alternative Anzahl von Argumenten bestimmen?
Die Eingabe- / Ausgabespezifikation, in die
&
übersetzt wird, ist funktionsspezifisch , sodass wir die Byte-Einsparungen optimieren.Der Abschnitt mit den Eingabe- / Ausgabeargumenten in der Hilfebeschreibung für jede Funktion wurde aktualisiert, um anzugeben, um welche alternative Anzahl von Ein- / Ausgängen es sich handelt (falls vorhanden). Die mögliche Anzahl der Eingabe- oder Ausgabeargumente wird als Bereich angezeigt und die Standardwerte für jedes Argument sind in Klammern angegeben. Die Eingabe- / Ausgabespezifikation, durch die ersetzt werden kann,
&
wird nach dem/
Zeichen in Klammern angezeigt .Hier ist der Abschnitt mit den Ein- / Ausgabeargumenten in der Hilfebeschreibung für
:
Wie hast du was festgestellt?
&
für jede Funktion bedeutet?Sehr vorsichtig. Mithilfe der StackExchange-API konnten wir alle MATL-Antworten herunterladen, die jemals in einer PPCG-Herausforderung verwendet wurden. Durch Analysieren jeder der Antworten konnten wir dann die Häufigkeit bestimmen, mit der jede Eingabe- / Ausgabespezifikation für jede Funktion verwendet wurde. Anhand dieser Informationen konnten wir dann objektiv die Eingabe- / Ausgabespezifikation identifizieren, die die
&
Metafunktion für jede Funktion darstellen sollte. Manchmal gab es keinen klaren Sieger, so viele Funktionen haben sich derzeit nicht&
definiert.Hier ist das Skript, das wir verwendet haben (leider ist es in MATLAB geschrieben und nicht MATL geschrieben).
Und hier ist ein Beispiel für das Histogramm von
$
/#
usagequelle
&
hieß das "Anzahl der Eingänge um 1 gegenüber dem Standard erhöhen". Sein Vorschlag erwies sich als viel nützlicherMachen Sie sich mit den Wahrheits- / Falschdefinitionen von MATL vertraut
Während
true
(T
) undfalse
(F
) eindeutig die Wahrheits- bzw. Falschausgabe darstellen, ist die weitestgehend vereinbarte Definition von Wahrheit / Falsch gibt uns ein wenig mehr Flexibilität in MATL.Die Definition besagt:
Wir können also einen schnellen MATL-Wahrheits- / Falschtest schreiben, der alle Eingaben durchläuft und anzeigt, ob sie als wahr oder falsch eingestuft wurden
Hier ist eine Online-Version.
Was dies in MATL bedeutet
In MATL (und daher in MATLAB und Octave) bedeutet dies, dass eine Bedingung als wahr betrachtet wird, wenn sie nicht leer ist und die realen Komponenten aller ihrer Werte nicht Null sind . Es gibt zwei Teile, die hervorgehoben werden sollten.
Nicht-Null : Dies bedeutet genau das, ungleich Null (
==
). Dies schließt positive Zahlen, negative Zahlen, Nicht-Null-Zeichen usw. ein. Sie können dies einfach überprüfen, indem Sie einen bestimmten Wert in einenlogical
Wert (g
) umwandeln oder verwenden~~
Alle Werte : Normalerweise betrachten wir Skalare als wahr oder falsch, aber in MATL können Skalare, Zeilenvektoren, Spaltenvektoren oder sogar mehrdimensionale Matrizen ausgewertet werden, und sie werden nur dann als wahr angesehen, wenn jeder einzelne Wert wahr ist Nicht-Null (wie oben definiert), sonst sind sie falsch. Hier einige Beispiele zur Veranschaulichung
Der Fall mit einer Kante ist, wie oben erwähnt, ein leeres Array
[]
, das immer als falsch betrachtet wird ( Beispiel ).Wie kann ich das nutzen, um besser zu golfen?
Wenn in der Abfrage nur erwähnt wird, dass Ihre Ausgabe wahr oder falsch sein sollte, können Sie die obige Definition wahrscheinlich ausnutzen, um ein paar Bytes Ihrer Antwort zu sparen. Um Verwirrung zu vermeiden, wird empfohlen, dass Sie in Ihre Antwort einen Link zum obigen Online-Wahrheits- / Falschtest einfügen, um zu erläutern, wie MATL-Wahrheits- / Falschwerte funktionieren.
Einige konkrete Beispiele:
Eine Antwort endet mit
A
. Wenn für die Abfrage eine wahrheitsgemäße oder falsche Ausgabe erforderlich ist und Sie Ihre Antwort mitall
(A
) beenden , um einen Skalar zu erstellen, können Sie dieses letzte Byte entfernen und Ihre Antwort bleibt korrekt (es sei denn, die Ausgabe ist[]
da[]
istfalse
aber[]A
isttrue
).Sicherstellen, dass ein Array nur einen eindeutigen Wert enthält : Verwendet
&=
anstelle vonun1=
. Wenn alle Werte in einem Array gleich sind, wird bei einem Vergleich der übertragenen Elemente in Bezug auf die Gleichheit eineN x N
Matrix aller Werte erstellt . Wenn nicht alle Werte gleich sind, enthält diese Matrix einige0
Werte und wird daher als falsch betrachtet.quelle
Implizite Eingabe
Die meisten Funktionen akzeptieren eine bestimmte Anzahl von Eingaben. Diese Eingaben werden von der Oberseite des Stapels übernommen. Wenn der obere Bereich des Stapels nicht genügend Argumente enthält, wird das verbleibende Argument aus der Eingabe gezogen. (Siehe Abschnitt 7.3 in der Dokumentation) Ich möchte die ursprüngliche Erklärung zitieren:
quelle
Logische Arrays können häufig als numerische Arrays verwendet werden
Sie können häufig die "
TF
" Notation anstelle von Array - Literalen aus Nullen und Einsen verwenden. Zum BeispielFTF
ist dasselbe wie[0,1,0]
, nur dasFTF
daslogical
Werte erzeugt , keinedouble
Werte. Dies ist normalerweise kein Problem, da jede arithmetische Operation logische Werte als Zahlen behandelt. Zum BeispielFTFQ
gibt[1,2,1]
(Q
ist "um 1 erhöhen").In einigen Fällen kann die Umwandlung einer Zahl in eine Binärdatei kürzer sein. Beispielsweise,
[1,0,1]
,TFT
und5B
sind gleich; wieder mit der Vorsicht, dass die beiden letzterenlogical
Werte sind.Ein Fall, in dem der Unterschied zwischen
TF
(logisch) und[1 0]
(numerisch) von Bedeutung ist, liegt vor, wenn er als Indizes verwendet wird. Ein Array des Typs,logical
der als Index verwendet wird, bedeutet: Elemente auswählen, die entsprechenT
, diejenigen verwerfen, die entsprechenF
. Also[10 20]TF)
produziert10
(wähle das erste Element aus), wohingegen[10 20][1 0])
produziert[10 20]
(der Index[1 0]
hat die Interpretation1:end
, das heißt, wähle alle Elemente des Arrays aus).quelle
Für Schleife der Größe n-1
Sollten Sie sie ersetzen
mit
um bis zu einem ganzen Byte oder mehr zu speichern .
quelle
@
/X@
in der Schleife oder nicht. Vielleicht können Sie einfach "Bytes speichern" sagenVerschieben Sie Dinge von hinter der Schleife in die Schleife, um das implizite Ende auszunutzen
Loop -
end
Anweisungen]
können, werden weggelassen , wenn kein Code hinter ihnen her ist. Sie werden implizit vom MATL-Parser gefüllt.Wenn Sie also Dinge von nach der Schleife in die Schleife verschieben können, können Sie das Finale speichern
]
.Im folgenden Beispiel wird die Anzahl der nachgestellten Nullen in der Fakultät einer Zahl ermittelt
N
(siehe hier ):1
bisN
.5
vorhanden ist.5
Auftritten (dies funktioniert, weil für jeden5
mindestens einer vorhanden ist2
).Die erste Idee war
:"@Yf5=]vs
(beachte, dass es Aussagen nach der Schleife gibt):Da
v
standardmäßig alle Stapelinhalte verkettet sind, können sie in die Schleife verschoben werden. Und da die Addition assoziativ ist,s
kann sie auch verschoben werden. Das steht]
am Ende des Codes und kann daher weggelassen werden:"@Yf5=vs
:quelle
Kürzere Möglichkeit, ein leeres numerisches Array zu definieren, wenn der Stapel leer ist
Zum Verschieben eines leeren numerischen Arrays, das Sie normalerweise verwenden
[]
. Wenn der Stapel jedoch leer ist, können Sie ein Byte mit speichernv
. Diese Funktion verknüpft standardmäßig alle Stapelinhalte vertikal. Wenn der Stapel also leer ist, wird das leere Array erstellt.Sie können es zum Beispiel hier in Aktion sehen .
quelle
Einige Funktionen sind gegenüber MATLAB oder Octave erweitert
Wenn Sie aus MATLAB oder Octave kommen, werden Sie feststellen, dass viele MATL-Funktionen den Funktionen in diesen Sprachen ähnlich sind. Aber in einigen von ihnen wurde die Funktionalität erweitert.
Betrachten Sie als Beispiel die
reshape
Funktion von MATLAB , die in MATL entsprichte
. Der Code - Schnipselreshape([10 20 30 40 50 60], 2, 3)
undreshape([10 20 30 40 50 60], 2, [])
bedeutet jeweils „umformen den Zeilenvektor[10 20 30 40 50 60
in eine 2 × 3 - Matrix“ oder „in eine 2-reihigen Matrix mit so vielen Spalten wie benötigt“. Das Ergebnis ist also in beiden Fällen das 2D-ArrayEtwas wie
reshape([10 20 30 40 50 60], 2, 2)
oderreshape([10 20 30 40 50 60], 5, [])
würde einen Fehler wegen inkompatibler Größen geben. Im ersten Fall entfernt MATL jedoch Elemente ( versuchen Sie es online! ) Oder füllt sie im zweiten mit Nullen ( online ausprobieren! )und
Andere Funktionen , die erweiterte Funktionalität im Vergleich zu ihren MATLAB Pendants sind (nicht erschöpfende Liste) haben
S
(sort
),Yb
(strsplit
),m
(ismember
),h
(horzcat
),v
(vertcat
),Zd
(gcd
),Zm
(lcm
),YS
(circshift
),YA
(dec2base
),ZA
(base2dec
),Z"
(blanks
).quelle
Ruft den Index des ersten Nicht-Null-Elements ab, falls vorhanden
Die
f
Funktion gibt die Indizes aller Nicht-Null-Elemente eines Arrays an. Häufig möchten Sie den Index des ersten Elements ungleich Null. Das wäref1)
: Bewerben Sie sichf
und wählen Sie das erste Element aus. Wenn das ursprüngliche Array jedoch keinen Wert ungleich Null enthält,f
wird ein leeres Array ausgegeben ([]
) , und der Versuch, das erste Element auszuwählen, führt zu einem Fehler.Eine übliche, robustere Anforderung besteht darin, den Index des ersten Elements zu erhalten falls mindestens eines vorhanden ist , und
[]
ansonsten. Dies könnte mit einerif
Verzweigung nach getan werdenf
, aber das ist byteteuer. Besser istfX<
es, die MinimalfunktionX<
auf den Ausgang von anzuwendenf
.X<
Gibt ein leeres Array zurück, wenn seine Eingabe ein leeres Array ist.Probieren Sie es online! (Beachten Sie, dass ein leeres Array überhaupt nicht angezeigt wird). Oder sieht ein Beispiel hierfür bei der Arbeit hier .
quelle
Generieren Sie einen Bereich, der so lang wie ein bestimmtes Array ist
TL; WR : verwenden
f
Option,n:
wenn das Array nur Elemente ungleich Null enthält.Häufig muss ein Array generiert werden,
[1 2 ... L]
in demL
die Anzahl der Elemente eines bestimmten Arrays angegeben ist. Die Standardmethode hierfür istn:
. Beispielsweise nimmt der Codetn:*
einen numerischen Vektor als Eingabe und berechnet jeden Eintrag multipliziert mit seinem Index.Wenn das angegebene Array garantiert nur Einträge ungleich Null enthält (z. B. positive ganze Zahlen oder eine Zeichenfolge mit druckbaren Zeichen),
n:
kann durch ersetzt werdenf
, wodurch ein Array mit den Indizes von Einträgen ungleich Null erstellt wird. So wird der obige Codetf*
, der 1 Byte spart.Einige ausführlichere Beispiele: 1 , 2 , 3 .
quelle
Effizientes Definieren von numerischen Array-Literalen
Es gibt einige Möglichkeiten, wie Sie beim Definieren von numerischen Array-Literalen Bytes speichern können. Links werden zu Beispielantworten gegeben, die diese verwenden. Diese wurden mit dem Analyseskript ermittelt erstellt @Suever .
Verkettung und vordefinierte Literale
Bei Arrays mit kleinen Zahlen können Sie manchmal Verkettungen (Funktionen
h
undv
) sowie vordefinierte Literale verwenden, um die Verwendung von Leerzeichen als Trennzeichen zu vermeiden: compare[2 4]
,2 4h
and2Kh
, die alle das Array definieren[2 4]
. Ähnliches gilt2K1v
für einen leeren Stack[2; 4; 1]
. Beispiel .Buchstaben in numerischen Array-Literalen
Bei etwas größeren Zahlen können Sie Leerzeichen sparen, indem Sie die Tatsache ausnutzen, dass einige Buchstaben numerische Bedeutungen in Array-Literalen haben. So kann man stattdessen
[3 5 2 7;-4 10 12 5]
verwenden[IAHC;dX12A]
. Beispiel .Insbesondere innerhalb von Array-Literalen,
O
,l
,H
I
K
Haben ihre üblichen Bedeutungen0
, ...,4
A
, ...,E
gemein5
, ...,9
X
meint10
a
, ...d
gemein-1
, ...,-4
J
undG
meine1j
und-1j
P
meintpi
Y
meintinf
N
bedeutetNaN
.String und aufeinanderfolgende Unterschiede
Bei größeren Zahlen
d
kann es hilfreich sein , eine Zeichenfolge zu definieren und ihre aufeinander folgenden Unterschiede (mit ) zu berechnen : Anstelle von können[20 10 35 -6]
Sie verwenden'!5?b\'d
. Dies funktioniert, weild
die Codepunkte der Zeichen zur Berechnung der Unterschiede verwendet werden. Beispiel .quelle