Wskazówki do gry w golfa w Octave


18

Jakie masz ogólne wskazówki na temat gry w golfa w Octave? Szukam pomysłów, które można by zastosować do problemów z golfem w kodzie, które są przynajmniej nieco specyficzne dla Octave (np. „Usuń komentarze” nie jest odpowiedzią). Proszę zamieścić jedną wskazówkę na odpowiedź.


Odpowiedzi:


9
  1. Gdy się dowiesz, że ajest on wolny od zerowych wartości, użycie nnz(a)oszczędza ci 2 znaki w porównaniu do numel(a).
  2. Wolę a(a==0)się a(find(a==0)).
  3. ~tjest krótszy niż t==0, a nawet ~~tkrótszy niż t!=0.
  4. 0*(1:n) jest krótszy niż zeros(1,n)
  5. Zasadniczo ||i &&, w przeciwieństwie do wielu innych operatorów, skalaryzuje wynik, gdy pierwszym argumentem jest skalar. W przypadku macierzy tylko niepuste macierze bez elementów równych zeru mają logiczną wartość true .

Dlatego możemy zrobić 0||mzamiast all(all(m))dowolnej matrycy.

Spróbuj 0||[1 1;1 0]i 0||[1 1;1 1]przekonaj się.

  1. Jeśli używasz wbudowanego interfejsu wiele razy, wykonaj uchwyt funkcji, aby zaoszczędzić znaki, np. f=@find. W przypadku krótkich nazw funkcji uzasadniają to co najmniej 3 wystąpienia, w przypadku długich - nawet w przypadku dwóch wystąpień.

  2. Gdy funkcja jest pojedynczą instrukcją, preferuj f=@(n)dosomething(n)notację niż function r=f(n)r=dosomething(n);endjedną.

  3. Niestety zmienne globalne muszą być deklarowane zarówno w zakresie globalnym, jak i w każdej funkcji, która ich używa. Ale jest wyjątek: @(n)...funkcje anonimowe „widzą” wszystkie zmienne z zakresu, z którego są wywoływane.

  4. Można to zrobić f(a=0,b=0)zamiast a=0;b=0;f(a,b).

  5. Wydaje się to nieudokumentowaną cechą, ale kolejność oceny jest od lewej do prawej (sprawdzone w wersji 3.8.1), możesz zrobić, zeros(a=n,b=a*a)aby zarówno utworzyć macierz anxn ^ 2 i zapisać jej numer wiersza i kolumny aoraz bzmienne.

  6. Tabela priorytetów operatora jest Twoim przyjacielem. Nie rób, b=(a==0)bo b=a==0to samo.


7

Nie pamiętam, w jakim wyzwaniu widziałem, że ktoś go używa (powiedz nam =), ale uznałem, że to fajna sztuczka:

Zwykle jeśli dodajesz macierze, musisz mieć taki sam rozmiar, ale dla macierzy jednowymiarowych (1xn i nx1) istnieje skrót (który nie działa w Matlabie):

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

daje taki sam efekt jak

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

Potem coś, o czym już wspominał pawel.boczarski: W Octave możesz (choć nie możesz w Matlabie) zdefiniować zmienne pomocnicze w uchwytach funkcji, A samo przypisanie zmiennej ma wartość przypisania, więc możesz naprawdę skrócić kod (cóż, to jest bezużyteczne przykład, ale dostaniesz lewę):

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

Następnie kolejną sztuczką (stosowaną również w Matlabie) jest nadużywanie ciągów do przechowywania (zakodowanych na stałe) liczb (ta zgrabna sztuczka została skradziona z feersum) , potrzebujesz tylko czegoś, co interpretuje ciąg jako liczbę, co jest tak proste, jak np. Dodanie zera:

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

Lub

sum('abc') == 294

Wierzę, że to miało być a+0, nie a+'0'. Poza tym wskazówki są fajne =)
Stewie Griffin

Racja, dzięki! PS: Czy możesz dodać += -= /=operatorów etc na liście poniżej?
flawr

1
+ajest krótszy niża+0
Luis Mendo

7

Za pomocą listy argumentów:

Oktawa jest w stanie uzyskać domyślne argumenty, dzięki czemu wyrażenia można oceniać na liście argumentów.

Ta funkcja jest przydatna, gdy chcemy obliczyć wyrażenie i użyć go wiele razy:

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

Jednym z przypadków użycia jest użycie indeksowanego przypisania do modyfikacji części tablicy i chcemy użyć tablicy:

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

Ale wyrażenie (a(2)=5)zwraca a(2)lub wyrażenie (a([1 3])=4)zwraca tablicę dwóch elementów. Żaden z nich nie zwraca całej tablicy. Możemy użyć listy argumentów:

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

W tym przypadku wynik przypisania indeksowanego jest przechowywany w zmiennej zastępczej, ba funkcja zwraca tablicę.


6

-W Octave można zastosować indeksowanie do wyrażenia tymczasowego, co jest zabronione w MATLAB i ta funkcja jest bardzo przydatna podczas gry w golfa. przykład:

Oktawa: [1 23 4 5 7](3:4) i jej odpowiednik MATLAB: a=[1 23 4 5 7];a(3:4)
Oktawa: hilb(4)(4:5,4:5) i jej odpowiednik MATLAB: h=hilb(4);h(4:5,4:5)
Oktawa: {1,4,{4 5 6},[7 ;3]}{3}i jej odpowiednik MATLAB: a={1,4,{4 5 6},[7 ;3]};a{3}
Oktawa: num2cell([1 2 3 4]){:}do utworzenia listy oddzielonej przecinkami
Oktawa:a'(:)'

-Czasami w funkcji anonimowej jako funkcji normalnej wymagamy oceny wielu wyrażeń, które obejmują przypisanie. Jedno podejście polega na tym, że możemy umieścić każde wyrażenie w komórce (ponieważ komórka może zawierać obiekt wielu typów) i kiedy potrzebujemy wartości każdego wyrażenia możemy użyć indeksowania do wyodrębnienia tego elementu.

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

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


@StewieGriffin Fajna wskazówka! Odpowiedź zaktualizowana!
rahnema1

5

Pomiń średniki!

Użyję tej odpowiedzi, aby zilustrować tę kwestię.

Oryginalny kod to:

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

Po usunięciu średników można go zmniejszyć do następujących, oszczędzając trzy bajty:

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

Można tego użyć w kilku miejscach i rzeczy, których nawet nie próbujesz, ponieważ często wygląda to na błąd składniowy.


1
rzeczy, których nawet nie próbujesz, ponieważ wygląda na to, że błąd składniowy często działa w skrócie Octave
Sanchises,

2

To jest proste, ale przydatne.

W Octave, ale nie MATLAB, możesz zrobić tak jak w C ++:

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

2

Kolejny prosty, ale użyteczny (niemożliwy w MATLAB):

Przypisz tę samą wartość do kilku zmiennych:

a=b=c=0;

2

Użyj eval!

Zainspirowany odpowiedzią Luisa Mendo tutaj .


Funkcje anonimowe są w większości przypadków krótsze niż tworzenie skryptu, który wymaga jednego lub więcej wywołań input(''). Minusem jest to, że pętle i modyfikacje zmiennych (takie jak zamiana dwóch elementów w macierzy) są niemożliwe .

Za pomocą evalmożna pobrać dane wejściowe, tak jak w przypadku zwykłej anonimowej funkcji, i uruchomić skrypt, tak jak w przypadku zwykłego skryptu:

Rozważ to :

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

W porównaniu z tym:

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

Kod jest identyczny, ale sekcja wejściowa jest znacznie krótsza.


Można to również wykorzystać do modyfikacji zmiennych wejściowych, takich jak to (za to dziękuję Luisowi Mendo !):

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

3
Kod jest identyczny Tylko brzydszy, wolniejszy i mniej czytelny. O co więcej możesz prosić? :-D
Luis Mendo


1

Powiązane, ale nie identyczne wskazówki dla MATLAB .

Mało znaną i rzadko używaną funkcją Octave jest to, że większość wbudowanych funkcji można wywoływać bez nawiasów, w którym to przypadku będą traktować wszystko, co następuje po niej, jako ciąg znaków (o ile nie zawiera spacji). Jeśli zawiera spacje, potrzebujesz cudzysłowu. Można to często wykorzystać do zapisania jednego lub dwóch bajtów podczas używania disp. Wszystkie następujące prace i daje ten sam rezultat:

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

Jeśli masz spacje, musisz mieć znaki cudzysłowu:

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

Inne, mniej przydatne przykłady to:

nnz PPCG
ans = 4

size PPCG
ans = 1  4

str2num 12
ans = 12
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.