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.
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.
Yanıtlar:
a
sıfır değerlerden arındırılmış, nnz(a)
karşılaştırıldığında 2 karakter yedekleri kullanarak numel(a)
.a(a==0)
et a(find(a==0))
.~t
daha kısadır t==0
ve hatta ~~t
daha kısadır t!=0
.0*(1:n)
daha kısa zeros(1,n)
||
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||m
yerine bunu yapabiliriz all(all(m))
.
İle deneyin 0||[1 1;1 0]
ve 0||[1 1;1 1]
kendinizi ikna.
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.
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
.
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".
Bunun f(a=0,b=0)
yerine yapmak mümkündür a=0;b=0;f(a,b)
.
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ı a
ve b
değişkenlerinde saklamak için yapabilirsiniz .
Operatör öncelik tablosu arkadaşınızdır. Yapma b=(a==0)
çünkü b=a==0
aynı şey.
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
a+0
, değil a+'0'
. Bunun dışında ipuçları güzel =)
+= -= /=
Aşağıdaki listeye vb. Operatörleri ekleyebilir misiniz ?
+a
daha kısadıra+0
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 b
ve fonksiyon diziyi döndürür.
-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}
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.
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
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;
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])`;
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