Consejos para jugar golf en Octave

18

¿Qué consejos generales tienes para jugar al golf en Octave? Estoy buscando ideas que se puedan aplicar a los problemas de golf de código en general que sean al menos algo específicos de Octave (por ejemplo, "eliminar comentarios" no es una respuesta). Por favor, publique un consejo por respuesta.

RAM
fuente
2
Relacionado, pero no un duplicado: Consejos para jugar golf en MATLAB
Dennis Jaheruddin

Respuestas:

9
  1. Una vez que sepa, eso aestá libre de valores cero, el uso le nnz(a)ahorra 2 caracteres en comparación numel(a).
  2. Prefiero a(a==0)a a(find(a==0)).
  3. ~tes más corto que t==0, e incluso ~~tes más corto que t!=0.
  4. 0*(1:n) es más corto que zeros(1,n)
  5. Generalmente, ||y &&, a diferencia de muchos otros operadores, escalar el resultado cuando el primer argumento es escalar. Para las matrices, solo las matrices no vacías sin elementos iguales a cero tienen el valor lógico de verdadero .

Por lo tanto, podemos hacer en 0||mlugar de all(all(m))cualquier matriz.

Prueba con 0||[1 1;1 0]y 0||[1 1;1 1]para convencerte a ti mismo.

  1. Cuando esté utilizando un generador incorporado varias veces, realice un control de función para ahorrar caracteres, por ejemplo. f=@find. Para nombres cortos de funciones, al menos 3 ocurrencias justifican esto, para nombres largos, incluso con dos ocurrencias.

  2. Cuando una función es una sola declaración, prefiera la f=@(n)dosomething(n)notación a function r=f(n)r=dosomething(n);enduna.

  3. Desafortunadamente, las variables globales deben declararse tanto en el ámbito global como en cada función que las use. Pero hay una excepción: las @(n)...funciones anónimas "ven" todas las variables del ámbito desde donde se llaman.

  4. Es posible hacer en f(a=0,b=0)lugar de a=0;b=0;f(a,b).

  5. Esto parece una característica no documentada, pero el orden de evaluación es de izquierda a derecha (marcado en v. 3.8.1), puede hacer zeros(a=n,b=a*a)tanto para crear una matriz ansn ^ 2 como para almacenar su número de fila y columna ay bvariables.

  6. La tabla de precedencia de operadores es tu amigo. No lo hagas b=(a==0)ya que b=a==0es lo mismo.

pawel.boczarski
fuente
7

No recuerdo en qué desafío lo vi usar a alguien (por favor díganos =), pero me pareció un buen truco:

Por lo general, si agrega matrices, debe tener el mismo tamaño, pero para las matrices unidimensionales (1xn y nx1) hay un acceso directo (que no funciona en Matlab):

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

produce el mismo efecto que

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

Entonces, algo que pawel.boczarski ya mencionó: en Octave puede (mientras no puede en Matlab) definir variables auxiliares dentro de los identificadores de función, Y una asignación de variable en sí misma tiene el valor de la asignación, por lo que realmente puede acortar el código (bueno, esto es inútil ejemplo, pero obtendrás el truco):

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

Luego, otro truco (también aplicable en Matlab) es abusar de las cadenas para almacenar números (codificados) (este truco ordenado es robado del feersum) , solo necesita algo que interprete la cadena como número, que es tan fácil como, por ejemplo, agregar cero:

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

O

sum('abc') == 294
falla
fuente
Creo que se supone que debe ser a+0, no a+'0'. Aparte de eso, los consejos son buenos =)
Stewie Griffin
Bien, gracias! PD: ¿Podría agregar los += -= /=operadores etc. en su lista a continuación?
falla
1
+aes más corto quea+0
Luis Mendo
7

Usando la lista de argumentos:

Octave es capaz de obtener argumentos predeterminados para que las expresiones se puedan evaluar en la lista de argumentos.

Esta característica es útil cuando queremos calcular una expresión y usarla varias veces:

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

Un caso de uso es cuando usamos una asignación indexada para modificar parte de una matriz y queremos usar la matriz:

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

Pero la expresión (a(2)=5)regresa a(2), o la expresión (a([1 3])=4)devuelve una matriz de dos elementos. Ninguno de los dos devuelve la matriz completa. Podemos usar la lista de argumentos:

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

Aquí el resultado de la asignación indexada se almacena en una variable ficticia by la función devuelve la matriz.

rahnema1
fuente
6

-En Octave es posible aplicar la indexación en una expresión temporal, una característica que está prohibida en MATLAB y esta característica es muy útil para el golf. ejemplo:

Octava: [1 23 4 5 7](3:4) y su equivalente MATLAB: a=[1 23 4 5 7];a(3:4)
Octava: hilb(4)(4:5,4:5) y su equivalente MATLAB: h=hilb(4);h(4:5,4:5)
Octava: {1,4,{4 5 6},[7 ;3]}{3}y su equivalente MATLAB: a={1,4,{4 5 6},[7 ;3]};a{3}
Octava: num2cell([1 2 3 4]){:}para la creación de una lista separada por comas
Octava:a'(:)'

-A veces, en una función anónima a partir de una función normal, necesitamos evaluar varias expresiones, que incluyen la asignación, un enfoque es que podemos colocar cada expresión en una celda (ya que la celda puede contener objetos de múltiples tipos) y cuando necesitamos el valor de cada expresión podemos usar indexación para extraer ese elemento.

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

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

rahnema1
fuente
@StewieGriffin ¡Buen consejo! Respuesta actualizada!
rahnema1
5

Omitir punto y coma!

Usaré esta respuesta para ilustrar el punto.

El código original fue:

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

Después de eliminar los puntos y comas, podría reducirse a lo siguiente, ahorrando tres bytes:

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

Esto se puede usar en muchos lugares, y cosas que ni siquiera intentas porque parece que un error de sintaxis a menudo funciona.

Stewie Griffin
fuente
1
cosas que ni siquiera intentas porque parece que un error de sintaxis a menudo funciona Octave en pocas palabras
Sanchises
2

Este es simple, pero útil.

En Octave, pero no en MATLAB, puede hacer lo mismo que en C ++:

x = 0  ->  x = 0
x++    ->  ans = 0
x      ->  x = 1
++x    ->  ans = 2
x      ->  x = 2
Stewie Griffin
fuente
2

Otro simple, pero útil (no es posible en MATLAB):

Asigne el mismo valor a varias variables:

a=b=c=0;
Stewie Griffin
fuente
2

Uso eval!

Inspirado por la respuesta de Luis Mendo aquí .


En la mayoría de los casos, las funciones anónimas son más cortas que crear un script que necesite una o más llamadas input(''). La desventaja es que los bucles y las modificaciones variables (como el intercambio de dos elementos en una matriz) son imposibles y engorrosos.

Con eval, puede obtener la entrada como lo hace con una función anónima normal, y ejecutar el script como lo hace con un script normal:

Considera esto :

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

En comparación con esto:

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

El código es idéntico, pero la sección de entrada es mucho más corta.


Esto también se puede usar para modificar variables de entrada, como esta (¡crédito a Luis Mendo por esto!):

f(x)eval('x([1,4])=x([4,1])`;
Stewie Griffin
fuente
3
El código es idéntico Solo más feo, más lento y menos legible. ¿Qué más puedes pedir? :-D
Luis Mendo
1

Usar en rows(a)lugar desize(a,1)

rahnema1
fuente
1

Consejos relacionados, pero no idénticos para MATLAB .

Una característica poco conocida y poco utilizada de Octave es que la mayoría de las funciones incorporadas se pueden llamar sin paréntesis, en cuyo caso tratarán lo que sigue como una cadena (siempre que no contenga espacios). Si contiene espacios, necesita comillas. Esto se puede usar con frecuencia para guardar un byte o dos cuando se usa disp. Todo el siguiente trabajo, y da el mismo resultado:

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

Si tiene espacios, entonces debe tener las comillas:

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

Otros ejemplos menos útiles incluyen:

nnz PPCG
ans = 4

size PPCG
ans = 1  4

str2num 12
ans = 12
Stewie Griffin
fuente