Consigli per giocare a golf a Octave


18

Quali consigli generali hai per giocare a golf in Octave? Sto cercando idee che possano essere applicate ai problemi del codice golf in generale che siano almeno in qualche modo specifiche di Octave (ad esempio "rimuovere i commenti" non è una risposta). Si prega di inviare un suggerimento per risposta.


2
Correlati, ma non un duplicato: consigli per giocare a golf in MATLAB
Dennis Jaheruddin,

Risposte:


9
  1. Una volta che lo sai, questo aè privo di valori zero, usando i tuoi nnz(a)risparmi 2 caratteri rispetto a numel(a).
  2. Preferiscono a(a==0)a a(find(a==0)).
  3. ~tè più corto di t==0e persino ~~tpiù corto di t!=0.
  4. 0*(1:n) è più corto di zeros(1,n)
  5. Generalmente ||e &&, a differenza di molti altri operatori, scalare il risultato quando il primo argomento è uno scalare. Per le matrici, solo le matrici non vuote senza elementi uguali a zero hanno il valore logico di vero .

Quindi, possiamo fare 0||minvece che all(all(m))per qualsiasi matrice.

Prova con 0||[1 1;1 0]e 0||[1 1;1 1]per convincerti.

  1. Quando si utilizza un built-in diverse volte, eseguire una maniglia di funzione per risparmiare caratteri, ad es. f=@find. Per nomi di funzioni brevi almeno 3 occorrenze lo giustificano, per quelli lunghi - anche con due ricorrenze.

  2. Quando una funzione è una singola istruzione, preferisci la f=@(n)dosomething(n)notazione a function r=f(n)r=dosomething(n);enduna.

  3. Sfortunatamente, le variabili globali devono essere dichiarate sia nell'ambito globale che in ciascuna funzione che le utilizza. Ma c'è un'eccezione: le @(n)...funzioni anonime "vedono" tutte le variabili dall'ambito da cui vengono chiamate.

  4. È possibile fare f(a=0,b=0)invece di a=0;b=0;f(a,b).

  5. Questa funzionalità sembra non documentata, ma l'ordine di valutazione va da sinistra a destra (verificato alla v. 3.8.1), è possibile fare zeros(a=n,b=a*a)sia per creare una matrice anxn ^ 2 sia per memorizzare il suo numero di riga e colonna ae le bvariabili.

  6. La tabella di precedenza degli operatori è tua amica. Non farlo b=(a==0)poiché b=a==0è lo stesso.


7

Non ricordo in quale sfida l'ho visto usare qualcuno (per favore dicci =), ma ho trovato questo un trucco pulito:

Di solito se aggiungi matrici devi avere le stesse dimensioni, ma per matrici monodimensionali (1xn e nx1) c'è un collegamento (che non funziona in Matlab):

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

produce lo stesso effetto di

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

Quindi qualcosa che pawel.boczarski ha già menzionato: in Octave puoi (anche se non puoi in Matlab) definire variabili ausiliarie all'interno degli handle di funzione, E un compito variabile ha il valore del compito in modo da poter davvero abbreviare il codice (beh, questo è un inutile esempio ma otterrai il trucco):

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

Quindi un altro trucco (applicabile anche in Matlab) è quello di abusare di stringhe per la memorizzazione di numeri (codificati) (questo trucco ordinato viene rubato dal feersum) , hai solo bisogno di qualcosa che interpreti la stringa come numero, che è facile come ad esempio l'aggiunta di zero:

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

O

sum('abc') == 294

Credo che dovrebbe essere a+0, no a+'0'. A parte questo, i consigli sono belli =)
Stewie Griffin,

Bene, grazie! PS: Potresti aggiungere gli += -= /=operatori etc nella tua lista qui sotto?
Flawr

1
+aè più corto dia+0
Luis Mendo il

7

Utilizzando l'elenco degli argomenti:

Octave è in grado di ottenere argomenti predefiniti in modo che le espressioni possano essere valutate nell'elenco degli argomenti.

Questa funzione è utile quando vogliamo calcolare un'espressione e usarla più volte:

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

Un caso d'uso è quando utilizziamo un compito indicizzato per modificare parte di un array e vogliamo usare l'array:

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

Ma l'espressione (a(2)=5)ritorna a(2)o l'espressione (a([1 3])=4)restituisce una matrice di due elementi. Né restituisce l'intero array. Possiamo usare la lista degli argomenti:

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

Qui il risultato dell'assegnazione indicizzata viene archiviato in una variabile fittizia be la funzione restituisce l'array.


6

-In Octave è possibile applicare l'indicizzazione su un'espressione temporanea, una funzione proibita in MATLAB e questa funzione è molto utile per giocare a golf. esempio:

Octave: [1 23 4 5 7](3:4) e il suo equivalente MATLAB: a=[1 23 4 5 7];a(3:4)
Octave: hilb(4)(4:5,4:5) e il suo equivalente MATLAB: h=hilb(4);h(4:5,4:5)
Octave: {1,4,{4 5 6},[7 ;3]}{3}e il suo equivalente MATLAB: a={1,4,{4 5 6},[7 ;3]};a{3}
Octave: num2cell([1 2 3 4]){:}per la creazione di un elenco separato da virgole
Octave:a'(:)'

-A volte in una funzione anonima come di una normale funzione abbiamo bisogno di valutare più espressioni, che includono l'assegnazione, un approccio è che possiamo posizionare ogni espressione in una cella (poiché la cella può contenere oggetti di più tipi) e quando abbiamo bisogno del valore di ogni espressione possiamo usare l'indicizzazione per estrarre quell'elemento.

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

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


@StewieGriffin Bel consiglio! Risposta aggiornata!
rahnema1,

5

Salta punto e virgola!

Userò questa risposta per illustrare il punto.

Il codice originale era:

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

Dopo aver rimosso i punti e virgola, potrebbe essere ridotto al seguente, salvando tre byte:

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

Questo può essere usato in parecchi posti e cose che non provi nemmeno perché sembra che un errore di sintassi funzioni spesso.


1
cose che non provi nemmeno perché sembra che un errore di sintassi funzioni spesso Octave in breve
Sanchises,

2

Questo è semplice ma utile.

In Octave, ma non MATLAB, puoi fare come in C ++:

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

2

Un altro semplice, ma utile (non possibile in MATLAB):

Assegna lo stesso valore a più variabili:

a=b=c=0;

2

Usa eval!

Ispirato dalla risposta di Luis Mendo qui .


Nella maggior parte dei casi, le funzioni anonime sono più brevi della creazione di uno script che richiede una o più chiamate input(''). Il rovescio della medaglia è che i cicli e le modifiche variabili (come lo scambio di due elementi in una matrice) sono impossibili e ingombranti.

Con eval, puoi recuperare l'input come fai con una normale funzione anonima ed eseguire lo script come fai con uno script normale:

Considera questo :

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

Rispetto a questo:

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

Il codice è identico, ma la sezione di input è molto più breve.


Questo può anche essere usato per modificare variabili di input, come questo (merito a Luis Mendo per questo!):

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

3
Il codice è identico Solo più brutto, più lento e meno leggibile. Cosa si può chiedere di più? MrGreen
Luis Mendo il


1

Suggerimenti correlati, ma non identici per MATLAB .

Una caratteristica poco nota e poco utilizzata di Octave è che la maggior parte delle funzioni integrate possono essere chiamate senza parentesi, nel qual caso tratteranno tutto ciò che segue come una stringa (purché non contenga spazi). Se contiene spazi sono necessarie le virgolette. Questo può essere usato frequentemente per salvare uno o due byte durante l'utilizzo disp. Tutto il seguente lavoro e dà lo stesso risultato:

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

Se hai spazi, devi avere le virgolette:

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

Altri esempi meno utili includono:

nnz PPCG
ans = 4

size PPCG
ans = 1  4

str2num 12
ans = 12
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.