Octave'de golf için ipuçları


18

Octave'de golf yapmak için hangi genel ipuçlarınız var? Ben en az biraz Octave (örneğin "yorumları kaldırmak" bir cevap değildir) genel olarak golf sorunları kod uygulanabilir uygulanabilir fikirler arıyorum. Lütfen cevap başına bir ipucu gönderin.


2
İlgili, ancak bir kopya değil: MATLAB'da golf için ipuçları
Dennis Jaheruddin

Yanıtlar:


9
  1. Bulduğunuzda, bu asıfır değerlerden arındırılmış, nnz(a)karşılaştırıldığında 2 karakter yedekleri kullanarak numel(a).
  2. Tercih a(a==0)et a(find(a==0)).
  3. ~tdaha kısadır t==0ve hatta ~~tdaha kısadır t!=0.
  4. 0*(1:n) daha kısa zeros(1,n)
  5. Genel olarak ||ve &&diğer birçok işleçten farklı olarak, ilk argüman bir skaler olduğunda sonucu skaler hale getirir. Matrisler için, yalnızca sıfıra eşit elemanlar içermeyen boş olmayan matrisler, mantıksal true değerine sahiptir .

Bu nedenle, herhangi bir matris 0||myerine bunu yapabiliriz all(all(m)).

İle deneyin 0||[1 1;1 0]ve 0||[1 1;1 1]kendinizi ikna.

  1. Bir yerleşkeyi birkaç kez kullanırken karakterleri yedeklemek için bir işlev tutamağı yapın, örn. f=@find. Kısa işlev adları için, en az 3 olay, iki olayda bile, uzun olanlar için bunu haklı çıkarır.

  2. Bir işlev tek bir deyim olduğunda, bir f=@(n)dosomething(n)gösterimi tercih edin function r=f(n)r=dosomething(n);end.

  3. Ne yazık ki, küresel değişkenler hem küresel kapsamda hem de bunları kullanan her işlevde bildirilmelidir. Ancak bir istisna vardır: anonim @(n)...işlevler, çağrıldıkları kapsamdaki tüm değişkenleri "görür".

  4. Bunun f(a=0,b=0)yerine yapmak mümkündür a=0;b=0;f(a,b).

  5. Bu belgelenmemiş bir özellik gibi görünse de, değerlendirme sırası soldan sağa doğrudur (v. zeros(a=n,b=a*a)3.8.1'de kontrol edilmiştir), hem anxn ^ 2 matrisi oluşturmak hem de satır ve sütun numarasını ave bdeğişkenlerinde saklamak için yapabilirsiniz .

  6. Operatör öncelik tablosu arkadaşınızdır. Yapma b=(a==0)çünkü b=a==0aynı şey.


7

Birinin kullandığını gördüğüm zorlukta hatırlamıyorum (lütfen bize bildirin =), ama bunu düzgün bir numara buldum:

Genellikle matrisler eklerseniz aynı boyuta sahip olmanız gerekir, ancak bir boyutlu (1xn ve nx1) matrisler için bir kısayol vardır (Matlab'da çalışmaz):

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

ile aynı etkiyi yaratır

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

Pawel.boczarski'nin daha önce bahsettiği bir şey: Octave'de (Matlab'da olamazken) fonksiyon tutamaçlarındaki yardımcı değişkenleri tanımlayabilirsiniz ve bir değişken atamanın kendisi atama değerine sahiptir, böylece kodu gerçekten kısaltabilirsiniz (iyi bir işe yaramaz örnek ama hile elde edersiniz):

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

Sonra başka bir hile (Matlab'da da geçerlidir) (sabit kodlu) sayıları saklamak için dizeleri kötüye kullanıyor (bu temiz hile feersum'dan çalındı) , sadece dizeyi sayı olarak yorumlayan bir şeye ihtiyacınız var, örneğin sıfır eklemek kadar kolay:

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

Veya

sum('abc') == 294

Bence öyle olmalı a+0, değil a+'0'. Bunun dışında ipuçları güzel =)
Stewie Griffin

Doğru, teşekkürler! Not: += -= /=Aşağıdaki listeye vb. Operatörleri ekleyebilir misiniz ?
flawr

1
+adaha kısadıra+0
Luis Mendo

7

Argüman listesini kullanma:

Octave varsayılan bağımsız değişkenleri alabilir, böylece ifadeler bağımsız değişken listesinde değerlendirilebilir.

Bu özellik, bir ifadeyi hesaplamak ve birden çok kez kullanmak istediğimizde kullanışlıdır:

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

Bir kullanım örneği, bir dizinin bir kısmını değiştirmek için dizine alınmış bir atama kullandığımız ve diziyi kullanmak istediğimiz durumdur:

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

Ancak ifade (a(2)=5)geri döner a(2)veya ifade (a([1 3])=4)iki öğe dizisi döndürür. İkisi de dizinin tamamını döndürmez. Argüman listesini kullanabiliriz:

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

Burada endeksli atamanın sonucu bir kukla değişken içinde saklanır bve fonksiyon diziyi döndürür.


6

-Oktave'de, geçici bir ifadeye indeksleme uygulamak mümkündür, MATLAB'da yasaklanan bir özellik ve bu özellik golf için çok yararlıdır. misal:

Oktav: [1 23 4 5 7](3:4) ve MATLAB eşdeğeri: a=[1 23 4 5 7];a(3:4)
Oktav:hilb(4)(4:5,4:5) ve MATLAB eşdeğeri: h=hilb(4);h(4:5,4:5)
Oktav: {1,4,{4 5 6},[7 ;3]}{3}ve MATLAB eşdeğeri: a={1,4,{4 5 6},[7 ;3]};a{3}
Oktav: num2cell([1 2 3 4]){:}virgülle ayrılmış liste oluşturmak için
Octave:a'(:)'

-Bazen normal bir işlev olarak anonim bir fonksiyonda, atamayı içeren birden fazla ifadeyi değerlendirmemiz gerekir, Bir yaklaşım, her ifadeyi bir hücreye yerleştirebilmemizdir (hücre birden çok türde nesne içerebileceğinden) ve değere ihtiyacımız olduğunda her ifadeden, bu öğeyi ayıklamak için dizin oluşturmayı kullanabiliriz.

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

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


@StewieGriffin Güzel bir ipucu! Yanıt güncellendi!
rahnema1

5

Noktalı virgülleri atla!

Kullanacağım Bu cevabı noktayı göstermek için .

Orijinal kod:

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

Noktalı virgülleri kaldırdıktan sonra, üç bayt tasarruf edilerek aşağıdakilere indirgenebilir:

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

Bu çok az yerde kullanılabilir ve denemediğiniz şeyler bile sözdizimi hatası genellikle işe yaradığı için görünür.


1
sözdizimi hatası gibi göründüğü için denemediğiniz şeyler genellikle özet olarak Octave çalışır
Sanchises

2

Bu basit ama kullanışlı bir şey.

Octave'de, ancak MATLAB'da değil, C ++ 'da olduğu gibi yapabilirsiniz:

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

2

Başka bir basit ama kullanışlı olan (MATLAB'de mümkün değil):

Aynı değeri birkaç değişkene atayın:

a=b=c=0;

2

Kullanın eval!

Luis Mendo cevabı esinlenerek burada .


Anonim işlevler çoğu durumda bir veya daha fazla çağrı gerektiren bir komut dosyası oluşturmaktan daha kısadır input(''). Dezavantajı, döngülerin ve değişken değişikliklerin (bir matristeki iki öğeyi değiştirmek gibi) imkansız olmasıdır. hantal .

İle eval girişi normal bir anonim işlevle yaptığınız gibi getirebilir ve komut dosyasını normal bir komut dosyasında yaptığınız gibi çalıştırabilirsiniz:

Düşünün bu :

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

Bununla karşılaştırıldığında:

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

Kod aynıdır, ancak giriş bölümü çok daha kısadır.


Bu, giriş değişkenlerini değiştirmek için de kullanılabilir (bunun için Luis Mendo'ya kredi verin !):

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

3
Kod aynıdır Sadece daha çirkin, daha yavaş ve daha az okunabilir. Daha ne isteyebilirsiniz? :-D
Luis Mendo


1

MATLAB için ilgili, ancak aynı değil ipuçları .

Octave'nin az bilinen ve az kullanılan bir özelliği, çoğu yerleşik fonksiyonun parantez olmadan çağrılabilmesidir, bu durumda onu takip eden her şeyi bir dize olarak (boşluk içermediği sürece) ele alacaklardır. Boşluklar içeriyorsa, tırnak işaretlerine ihtiyacınız vardır. Bu, kullanırken bir veya iki bayt kaydetmek için sıklıkla kullanılabilir disp. Aşağıdaki tüm işler ve aynı sonucu verir:

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

Boşluklarınız varsa, tırnak işaretlerine sahip olmalısınız :

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

Diğer, daha az kullanışlı örnekler şunları içerir:

nnz PPCG
ans = 4

size PPCG
ans = 1  4

str2num 12
ans = 12
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.