Conseils pour jouer au golf à Octave

18

Quels conseils avez-vous pour jouer au golf à Octave? Je recherche des idées qui peuvent être appliquées aux problèmes de golf de code en général qui sont au moins quelque peu spécifiques à Octave (par exemple, "supprimer les commentaires" n'est pas une réponse). Veuillez poster un pourboire par réponse.

RAM
la source
2
Connexes, mais pas en double: Conseils pour jouer au golf à MATLAB
Dennis Jaheruddin

Réponses:

9
  1. Une fois que vous savez, cela ane contient aucune valeur nulle, en utilisant des nnz(a)pièces de rechange de 2 caractères par rapport à numel(a).
  2. Préférez a(a==0)à a(find(a==0)).
  3. ~test plus court que t==0, et même ~~test plus court que t!=0.
  4. 0*(1:n) est plus court que zeros(1,n)
  5. Généralement ||et &&, contrairement à de nombreux autres opérateurs, scalarisez le résultat lorsque le premier argument est un scalaire. Pour les matrices, seules les matrices non vides sans éléments égaux à zéro ont la valeur logique true .

Par conséquent, nous pouvons faire à la 0||mplace de all(all(m))n'importe quelle matrice.

Essayez avec 0||[1 1;1 0]et 0||[1 1;1 1]pour vous convaincre.

  1. Lorsque vous utilisez un module intégré plusieurs fois, effectuez une gestion de fonction pour épargner des caractères, par exemple. f=@find. Pour les noms de fonction courts, au moins 3 occurrences justifient cela, pour les longues - même avec deux occurrences.

  2. Lorsqu'une fonction est une instruction unique, préférez la f=@(n)dosomething(n)notation à function r=f(n)r=dosomething(n);endune.

  3. Malheureusement, les variables globales doivent être déclarées à la fois dans la portée globale et dans chaque fonction qui les utilise. Mais il y a une exception: les @(n)...fonctions anonymes "voient" toutes les variables de la portée d'où elles sont appelées.

  4. Il est possible de faire à la f(a=0,b=0)place de a=0;b=0;f(a,b).

  5. Cette fonctionnalité semble non documentée, mais l'ordre d'évaluation est de gauche à droite (vérifié à la v. 3.8.1), vous pouvez zeros(a=n,b=a*a)à la fois créer la matrice anxn ^ 2 et stocker son numéro de ligne et de colonne dans aet les bvariables.

  6. La table de priorité des opérateurs est votre ami. Ne faites pas b=(a==0)puisque b=a==0c'est pareil.

pawel.boczarski
la source
7

Je ne me souviens pas dans quel défi je l'ai vu quelqu'un utiliser (veuillez nous dire =), mais j'ai trouvé que c'était une astuce intéressante:

Habituellement, si vous ajoutez des matrices, vous devez avoir la même taille, mais pour les matrices unidimensionnelles (1xn et nx1), il existe un raccourci (qui ne fonctionne pas dans Matlab):

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

produit le même effet que

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

Puis quelque chose que pawel.boczarski a déjà mentionné: Dans Octave, vous pouvez (alors que vous ne pouvez pas dans Matlab) définir des variables auxiliaires dans les poignées de fonction, ET une affectation de variable elle-même a la valeur de l'affectation afin que vous puissiez vraiment raccourcir le code (eh bien c'est inutile exemple mais vous aurez l'astuce):

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

Ensuite, une autre astuce (également applicable dans Matlab) consiste à abuser des chaînes pour stocker des numéros (codés en dur) (cette astuce est volée à feersum) , vous avez juste besoin de quelque chose qui interprète la chaîne comme un nombre, ce qui est aussi facile que par exemple en ajoutant zéro:

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

Ou

sum('abc') == 294
flawr
la source
Je crois que c'est censé l'être a+0, non a+'0'. A part ça, les conseils sont sympas =)
Stewie Griffin
D'accord, merci! PS: Pourriez-vous ajouter les += -= /=opérateurs etc dans votre liste ci-dessous?
2015
1
+aest plus court quea+0
Luis Mendo
7

Utilisation de la liste d'arguments:

Octave est capable d'obtenir des arguments par défaut afin que les expressions puissent être évaluées dans la liste des arguments.

Cette fonctionnalité est utile lorsque nous voulons calculer une expression et l'utiliser plusieurs fois:

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

Un cas d'utilisation est lorsque nous utilisons une affectation indexée pour modifier une partie d'un tableau et que nous voulons utiliser le tableau:

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

Mais l'expression (a(2)=5)renvoie a(2)ou l'expression (a([1 3])=4)renvoie un tableau à deux éléments. Aucun ne renvoie la totalité du tableau. Nous pouvons utiliser la liste d'arguments:

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

Ici, le résultat de l'affectation indexée est stocké dans une variable fictive bet la fonction renvoie le tableau.

rahnema1
la source
6

-En Octave, il est possible d'appliquer l'indexation sur une expression temporaire, une fonctionnalité interdite dans MATLAB et cette fonctionnalité est très utile pour le golf. exemple:

Octave: [1 23 4 5 7](3:4) et son équivalent MATLAB: a=[1 23 4 5 7];a(3:4)
Octave: hilb(4)(4:5,4:5) et son équivalent MATLAB: h=hilb(4);h(4:5,4:5)
Octave: {1,4,{4 5 6},[7 ;3]}{3}et son équivalent MATLAB: a={1,4,{4 5 6},[7 ;3]};a{3}
Octave: num2cell([1 2 3 4]){:}pour la création d'une liste séparée par des virgules
Octave:a'(:)'

-Parfois dans une fonction anonyme comme une fonction normale, nous avons besoin d'évaluer plusieurs expressions, qui incluent l'affectation, Une approche est que nous pouvons placer chaque expression dans une cellule (car la cellule peut contenir un objet de plusieurs types) et quand nous avons besoin de la valeur de chaque expression, nous pouvons utiliser l'indexation pour extraire cet élément.

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

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

rahnema1
la source
@StewieGriffin Nice tip! Réponse mise à jour!
rahnema1
5

Sautez les points-virgules!

Je vais utiliser cette réponse pour illustrer le point.

Le code d'origine était:

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

Après avoir supprimé les points-virgules, il peut être réduit comme suit, économisant trois octets:

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

Cela peut être utilisé à plusieurs endroits, et des choses que vous n'essayez même pas, car il semble qu'une erreur de syntaxe fonctionne souvent.

Stewie Griffin
la source
1
des trucs que vous n'essayez même pas car il semble qu'une erreur de syntaxe fonctionne souvent Octave en un mot
Sanchises
2

Ceci est simple mais utile.

Dans Octave, mais pas MATLAB, vous pouvez faire comme en C ++:

x = 0  ->  x = 0
x++    ->  ans = 0
x      ->  x = 1
++x    ->  ans = 2
x      ->  x = 2
Stewie Griffin
la source
2

Un autre simple, mais utile (impossible dans MATLAB):

Attribuez la même valeur à plusieurs variables:

a=b=c=0;
Stewie Griffin
la source
2

Utilisez eval!

Inspiré par la réponse de Luis Mendo ici .


Les fonctions anonymes sont dans la plupart des cas plus courtes que la création d'un script nécessitant un ou plusieurs appels à input(''). L'inconvénient est que les boucles et les modifications variables (telles que l'échange de deux éléments dans une matrice) sont impossibles à réaliser.

Avec eval, vous pouvez récupérer l'entrée comme vous le faites avec une fonction anonyme normale et exécuter le script comme vous le faites avec un script normal:

Considérez ceci :

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

Par rapport à cela:

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

Le code est identique, mais la section d'entrée est beaucoup plus courte.


Cela peut également être utilisé pour modifier des variables d'entrée, comme ceci (crédit à Luis Mendo pour cela!):

f(x)eval('x([1,4])=x([4,1])`;
Stewie Griffin
la source
3
Le code est identique Seulement plus laid, plus lent et moins lisible. Que peux tu demander de plus? :-D
Luis Mendo
1

Utiliser rows(a)au lieu desize(a,1)

rahnema1
la source
1

Astuces connexes, mais pas identiques pour MATLAB .

Une caractéristique peu connue et peu utilisée d'Octave est que la plupart des fonctions intégrées peuvent être appelées sans parenthèses, auquel cas elles traiteront tout ce qui la suit comme une chaîne (tant qu'elle ne contient pas d'espaces). S'il contient des espaces, vous avez besoin de guillemets. Cela peut fréquemment être utilisé pour enregistrer un ou deux octets lors de l'utilisation disp. Tout le travail suivant, et donne le même résultat:

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

Si vous avez des espaces, vous devez avoir les guillemets:

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

Voici d'autres exemples moins utiles:

nnz PPCG
ans = 4

size PPCG
ans = 1  4

str2num 12
ans = 12
Stewie Griffin
la source