Tipps zum Golfen in Octave


18

Welche allgemeinen Tipps haben Sie zum Golfen in Octave? Ich bin auf der Suche nach Ideen, die sich generell auf Code-Golf-Probleme anwenden lassen, die zumindest etwas Octave-spezifisch sind (z. B. "Kommentare entfernen" ist keine Antwort). Bitte posten Sie einen Tipp pro Antwort.


2
Verwandte, aber kein Duplikat: Tipps zum Golfen in MATLAB
Dennis Jaheruddin

Antworten:


9
  1. Wenn Sie wissen, dass dies akeine Nullwerte sind, nnz(a)sparen Sie 2 Zeichen im Vergleich zu numel(a).
  2. Bevorzugen a(a==0)zu a(find(a==0)).
  3. ~tist kürzer als t==0und sogar ~~tkürzer als t!=0.
  4. 0*(1:n) ist kürzer als zeros(1,n)
  5. Im Allgemeinen ||und &&im Gegensatz zu vielen anderen Operatoren skalieren Sie das Ergebnis, wenn das erste Argument ein Skalar ist. Bei Matrizen haben nur nicht leere Matrizen ohne Elemente gleich Null den logischen Wert true .

Daher können wir 0||mstatt all(all(m))für jede Matrix tun .

Versuchen Sie es mit 0||[1 1;1 0]und 0||[1 1;1 1]überzeugen Sie sich.

  1. Wenn Sie eine eingebaute Funktion mehrmals verwenden, verwenden Sie ein Funktionshandle, um Zeichen zu sparen, z. f=@find. Bei kurzen Funktionsnamen begründen mindestens 3 Vorkommen dies, bei langen - auch bei zwei Vorkommen.

  2. Wenn eine Funktion eine einzelne Anweisung ist, ziehen Sie die f=@(n)dosomething(n)Notation function r=f(n)r=dosomething(n);endeiner vor.

  3. Leider müssen globale Variablen sowohl im globalen Gültigkeitsbereich als auch in jeder Funktion, die sie verwendet, deklariert werden. Es gibt jedoch eine Ausnahme: Anonyme @(n)...Funktionen "sehen" alle Variablen aus dem Bereich, aus dem sie aufgerufen werden.

  4. Es ist möglich, f(a=0,b=0)anstatt zu tun a=0;b=0;f(a,b).

  5. Dies scheint eine undokumentierte Funktion zu sein, aber die Auswertungsreihenfolge ist von links nach rechts ( zeros(a=n,b=a*a)markiert in Version 3.8.1 ). Sie können sowohl eine anxn ^ 2-Matrix erstellen als auch deren Zeilen- und Spaltennummer in aund bVariablen speichern .

  6. Die Operator-Rangliste ist Ihr Freund. Tun Sie das nicht, b=(a==0)da b=a==0es dasselbe ist.


7

Ich kann mich nicht erinnern, in welcher Herausforderung ich jemanden gesehen habe (bitte sagen Sie uns =), aber ich fand das ein ordentlicher Trick:

Wenn Sie Matrizen hinzufügen, müssen Sie normalerweise dieselbe Größe haben, aber für eindimensionale Matrizen (1xn und nx1) gibt es eine Verknüpfung (die in Matlab nicht funktioniert):

z = (1:5)+(6:10)';

erzeugt den gleichen Effekt wie

[x,y]=meshgrid(1:5,6:10);
z = x+y;

Dann etwas, das pawel.boczarski bereits erwähnt hat: In Octave können Sie (während Sie es in Matlab nicht können) Hilfsvariablen in Funktionshandles definieren, UND eine Variablenzuweisung selbst hat den Wert der Zuweisung, sodass Sie Code wirklich verkürzen können (nun, das ist nutzlos) Beispiel, aber Sie werden den Trick bekommen):

f=@(n)(z=n+1)*z; %returns (n+1)^2

Dann ist ein anderer Trick (auch in Matlab anwendbar) der Missbrauch von Zeichenfolgen zum Speichern von (fest codierten) Zahlen (dieser nette Trick wird aus Feersum gestohlen) . Sie benötigen lediglich etwas, das die Zeichenfolge als Zahl interpretiert, was so einfach ist wie z. B. das Hinzufügen von Null:

a = 'abc';
a+0 %returns
[97 98 99]

Oder

sum('abc') == 294

Ich glaube, das soll es a+0nicht sein a+'0'. Ansonsten sind die Tipps nett =)
Stewie Griffin

Richtig, danke! PS: Könnten Sie die += -= /=etc-Operatoren unten in Ihre Liste aufnehmen?
Fehler

1
+aist kürzer alsa+0
Luis Mendo

7

Verwenden der Argumentliste:

Octave kann Standardargumente abrufen, sodass Ausdrücke in der Argumentliste ausgewertet werden können.

Diese Funktion ist nützlich, wenn wir einen Ausdruck berechnen und mehrfach verwenden möchten:

f = @(x,a=sort(x))a(a>.5);

Ein Anwendungsfall ist, wenn wir einen Teil eines Arrays mithilfe einer indizierten Zuweisung ändern und das Array verwenden möchten:

a=[1 2 3 4]
a(2)=5;

Der Ausdruck gibt jedoch (a(2)=5)zurück a(2), oder der Ausdruck (a([1 3])=4)gibt ein Array mit zwei Elementen zurück. Weder gibt das gesamte Array zurück. Wir können die Argumentliste verwenden:

f=@(a=[1 2 3 4],b=a(2)=5)a;

Hier wird das Ergebnis der indizierten Zuordnung in einer Dummy-Variablen gespeichert bund die Funktion gibt das Array zurück.


6

-In Octave ist es möglich, die Indexierung auf einen temporären Ausdruck anzuwenden, eine Funktion, die in MATLAB verboten ist, und diese Funktion ist sehr nützlich für das Golfen. Beispiel:

Octave: [1 23 4 5 7](3:4) und sein MATLAB-Äquivalent: a=[1 23 4 5 7];a(3:4)
Octave: hilb(4)(4:5,4:5) und sein MATLAB-Äquivalent: h=hilb(4);h(4:5,4:5)
Octave: {1,4,{4 5 6},[7 ;3]}{3}und sein MATLAB-Äquivalent: a={1,4,{4 5 6},[7 ;3]};a{3}
Octave: num2cell([1 2 3 4]){:}zum Erstellen einer durch Kommas getrennten Liste
Octave:a'(:)'

- Manchmal müssen wir in einer anonymen Funktion als normale Funktion mehrere Ausdrücke auswerten, einschließlich Zuweisung. Ein Ansatz ist, dass wir jeden Ausdruck in eine Zelle platzieren können (da die Zelle Objekte mehrerer Typen enthalten kann) und wann wir den Wert benötigen jedes Ausdrucks können wir Indizierung verwenden, um dieses Element zu extrahieren.

{1,4,{4 5 6},[7 ;3]}{3}
oder

{a=1,b=4,c={4 5 6},[b ;3]}{4}


@StewieGriffin Netter Tipp! Antwort aktualisiert!
rahnema1

5

Semikolons überspringen!

Ich werde diese Antwort verwenden , um den Punkt zu veranschaulichen.

Der ursprüngliche Code war:

function f(x);if~movefile('f.m',x);disp("+-+\n| |\n+-+");end

Nach dem Entfernen von Semikolons kann der Wert auf die folgenden drei Bytes reduziert werden:

function f(x)if~movefile('f.m',x)disp("+-+\n| |\n+-+")end

Dies kann an vielen Stellen verwendet werden und Dinge, die Sie nicht einmal ausprobieren, weil es so aussieht, als würde ein Syntaxfehler häufig funktionieren.


1
Dinge, die Sie nicht einmal probieren, weil es so aussieht, als würde ein Syntaxfehler Octave in
aller

2

Dies ist eine einfache, aber nützliche.

In Octave, aber nicht in MATLAB, können Sie wie in C ++ vorgehen:

x = 0  ->  x = 0
x++    ->  ans = 0
x      ->  x = 1
++x    ->  ans = 2
x      ->  x = 2

2

Ein weiteres einfaches, aber nützliches (in MATLAB nicht möglich):

Weisen Sie mehreren Variablen denselben Wert zu:

a=b=c=0;

2

Verwenden Sie eval!

Inspiriert von Luis Mendos Antwort hier .


Anonyme Funktionen sind in den meisten Fällen kürzer als das Erstellen eines Skripts, für das ein oder mehrere Aufrufe erforderlich sind input(''). Der Nachteil ist, dass Schleifen und variable Modifikationen (wie das Austauschen von zwei Elementen in einer Matrix) unmöglich umständlich sind.

Mit evalkönnen Sie die Eingabe wie mit einer normalen anonymen Funktion abrufen und das Skript wie mit einem normalen Skript ausführen:

Betrachten Sie dies :

c=(i=@input)('');N=i('');A=i('');for C=c,A(flip(k))=A(k=[x=find(A==C),N^2+1-x]);end,A

Im Vergleich dazu:

@(c,N,A)eval('for C=c,A(flip(k))=A(k=[x=find(A==C),N^2+1-x]);end,A')

Der Code ist identisch, aber der Eingabeabschnitt ist viel kürzer.


Dies kann auch verwendet werden, um Eingabevariablen wie folgt zu ändern (wir danken Luis Mendo dafür!):

f(x)eval('x([1,4])=x([4,1])`;

3
Der Code ist identisch. Nur hässlicher, langsamer und weniger lesbar. Was können Sie mehr verlangen? :-D
Luis Mendo


1

Verwandte, aber nicht identische Tipps für MATLAB .

Ein wenig bekanntes und wenig genutztes Merkmal von Octave ist, dass die meisten eingebauten Funktionen ohne Klammern aufgerufen werden können. In diesem Fall behandeln sie alles, was darauf folgt, als Zeichenfolge (solange es keine Leerzeichen enthält). Wenn es Leerzeichen enthält, benötigen Sie Anführungszeichen. Dies kann häufig verwendet werden, um ein oder zwei Bytes bei der Verwendung zu speichern disp. Alle folgenden Arbeiten und gibt das gleiche Ergebnis:

disp('Hello')
disp Hello
disp"Hello"

Wenn Sie Leerzeichen haben, müssen Sie die Anführungszeichen haben:

disp('Hello, World!')
disp"Hello, World!"

Andere, weniger nützliche Beispiele sind:

nnz PPCG
ans = 4

size PPCG
ans = 1  4

str2num 12
ans = 12
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.