Wskazówki do gry w golfa w MATLAB

14

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

Baran
źródło
3
Powiązane, ale nie duplikat: Wskazówki dotyczące gry w golfa w Octave
Dennis Jaheruddin

Odpowiedzi:

10

Coś, co trzeba wiedzieć przed rozpoczęciem gry w golfa:

W obliczeniach MATLAB znak zachowuje się tak samo jak kod ascii.

'abc' - 'a'  % Returns: [0 1 2]
'123' - '0'  % Returns: [1 2 3]
'“' == 8220  % Returns: 1 (logical)
'a':'e'==100 % Returns: [0 0 0 1 0] (logical)
Dennis Jaheruddin
źródło
9

Skracanie nazw nieruchomości

W MATLAB ciągi identyfikujące właściwości można skracać, o ile nie powoduje to niejednoznaczności.

plot(X,'C','k') % Ambiguous property found.
plot(X,'Co','k') % Expands to Color  (black)

To faktycznie dało mi wyzwanie :)

Sanchises
źródło
2
Bardzo fajnie, choć odpowiedź jest poprawna. Chcę podkreślić, że dotyczy to nazw name, valuepar, jak pokazano powyżej. (Więc nie do rzeczy takich jak sort(rand(4,1),'descend'))
Dennis Jaheruddin
1
To odnosi się do niektórych z tych rzeczy też, jak conv(1:5,[1 1],'s')zamiastconv(1:5,[1 1],'same')
Luis Mendo
6

Rzucanie jako char można wykonać przez konkatenację z char:

x='a'+magic(5) % Array with character codes of several letters

char(x) % The standard way
['' x] % The compact way

Chociaż oszczędza tylko jeden znak, można go używać dość często.

Dennis Jaheruddin
źródło
5

Ciągi są tylko wektorami wierszy znaków. Oznacza to, że zamiast

for i=numel(str)
    a=str(i)
    ...
end

możesz po prostu pisać

for(a=str)
    ...
end

Pierwszy raz użyłem tego: /codegolf//a/58387/32352

Sanchises
źródło
4

Korzenie jedności poprzez dyskretną transformatę Fouriera

Biorąc pod uwagę dodatnią liczbę całkowitą n, standardowym sposobem generowania n-tego korzenia jedności jest

exp(2j*pi*(0:n-1)/n)

To daje korzenie zaczynające się 1i poruszające w dodatnim kierunku kątowym. Jeśli kolejność nie ma znaczenia, można to skrócić

exp(2j*pi*(1:n)/n)

Ponieważ exp(2j*pi/4)jest równa jednostce urojonej ( j), można to zapisać w bardziej zwięzły sposób (sztuczka z powodu @flawr ):

j.^(4*(0:n-1)/n)

lub

j.^(4*(1:n)/n)

Ale dyskretna transformata Fouriera zapewnia jeszcze krótszą drogę (dzięki @flawr do usunięcia dwóch niepotrzebnych nawiasów):

fft(1:n==n)

co daje korzenie rozpoczynające się 1i poruszające w dodatnim kierunku kątowym; lub

fft(1:n==2)

który zaczyna się 1i porusza w ujemnym kierunku kątowym.


Wypróbuj wszystkie powyższe tutaj .

Luis Mendo
źródło
Świetna sztuczka! Możesz nawet fft(1:n==2)
zagrać w
@flawr Nigdy nie znam zasad pierwszeństwa ... Dzięki!
Luis Mendo
3

nnz może czasami zaoszczędzić kilka bajtów:

  • Wyobraź sobie, że chcesz sumę logicznej macierzy A. Zamiast sum(sum(A))lub sum(A(:))możesz użyć nnz(a)( nnzdomyślnie dotyczy (:)).
  • Jeśli chcesz poznać liczbę elementów tablicy i możesz być pewien, że nie ma zer, zamiast tego numel(x)możesz użyć nnz(x). Dotyczy to na przykład xciągów znaków.
Luis Mendo
źródło
3

Iteracja nad wektorami w macierzach.

Biorąc pod uwagę zbiór wektorów jako macierzy, możesz iterować po nich za pomocą pojedynczej pętli for jak

for v=M
    disp(v);
end

podczas gdy „tradycyjnie” prawdopodobnie zrobiłbyś to tak

for k=1:n
    disp(M(:,k));
end

Właśnie dowiedziałem się o tej sztuczce od @Suever w tym wyzwaniu .

wada
źródło
3

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

Mało znaną i mało używaną cechą MATLAB i 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 nim, 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 bajtu przy użyciu disp:

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

Użyłem tego dwukrotnie w „Jak wysoko możesz liczyć?” -wyzwanie:

strchr sssssssssssssst t

jest równoważne strchr('sssssssssssssst','t')i zwraca 15.

nnz nnnnnnnnnnnnnn

jest równoważne nnz('nnnnnnnnnnnnnn')i zwraca 14.

Takie rzeczy gt r steż działają (równoważne z 'r'>'s'lub gt('r','s').

Stewie Griffin
źródło
2

Wbudowane onesi zerossą zazwyczaj stratą miejsca. Możesz osiągnąć ten sam wynik, po prostu mnożąc tablicę / macierz (o pożądanym rozmiarze) przez 0 (aby uzyskać wynik zeros) i dodaj 1, jeśli chcesz wynik ones.

d = rand(5,2);

%// Using zeros
z = zeros(size(d));

%// Not using zeros
z = d*0;

%// Using ones
o = ones(size(d));

%// Not using ones
o = 1+d*0

Działa to również, jeśli chcesz utworzyć wektor kolumny lub wiersza zera lub jedynek o rozmiarze jednego wymiaru macierzy.

p = rand(5,2);

z = zeros(size(p,1), 1);
z = 0*p(:,1);

o = ones(size(p, 1), 1);
o = 1+0*p(:,1);

Jeśli chcesz utworzyć macierz o określonym rozmiarze, którego możesz użyć, zerosale możesz również przypisać ostatni element do 0, a MATLAB wypełni resztę.

%// This
z = zeros(2,3);

%// vs. This
z(2,3) = 0;
Suever
źródło
2
Lubię korzystać ~(1:n) do wektorów 1-d zero.
sintax
2

Jądra konwolucji 2D

To może temat niszowy, ale najwyraźniej niektórzy ludzie lubią używać splotu do różnych rzeczy tutaj. [wymagany cytat]

W 2D często potrzebne są następujące jądra:

0 1 0
1 1 1
0 1 0

Można to osiągnąć za pomocą

v=[1,2,1];v'*v>1 %logical
v=[1,0,1];1-v'*v  %as numbers

który jest krótszy niż

[0,1,0;1,1,1;0,1,0]

Innym często używanym jądrem jest

0 1 0
1 0 1
0 1 0

które można skrócić za pomocą

v=[1,-1,1];v'*v<0   % logical
[0,1,0;1,0,1;0,1,0] % naive verison
wada
źródło
Drugie jądro jako liczby, ta sama liczba bajtów:toeplitz([0 1 0])
Luis Mendo
2

Dość często używam meshgridlubndgrid , powiedzmy, że chcemy obliczyć obraz mandelbrota, a następnie inicjujemy np

[x,y]=meshgrid(-2:1e-2:1,-1:1e-2,1)

Teraz dla zestawu mandelbrota potrzebujemy kolejnej macierzy cwielkości xi yzainicjowanej zerami. Można to łatwo zrobić, pisząc:

c=x*0;

Możesz także zainicjować go do innej wartości:

c=x*0+3;

Ale możesz faktycznie zaoszczędzić niektóre bajty, po prostu dodając inny wymiar w meshgrid/ndgrid:

[x,y,c]=meshgrid(-2:1e-2:1,-1:1e_2,1, 0); %or for the value 3
[x,y,c]=meshgrid(-2:1e-2:1,-1:1e_2,1, 3);

Możesz to zrobić tak często, jak chcesz:

[x,y,c1,c2,c3,c4,c5]=meshgrid(-2:1e-2:1,-1:1e_2,1, 1,pi,exp(3),1e5,-3i)
wada
źródło
Pamiętaj, że w międzyczasie odbywa się automatyczne nadawanie: W wielu przypadkach pierwszy przykład można zastąpić x=-2:1d-2:1;y=x'.
wada
0

Podsumowanie sekwencji funkcji

  • Do sumowania funkcji f (x_n), gdzie n jest wektorem kolejnych liczb całkowitych, zaleca się feval zamiast symsum.

    Syms x;symsum(f(x),x,1,n);
    Sum(feval(@(x)f(x),1:n));
    

    Zauważ, że operacja elementarna .* i ./jest konieczne zamiast operacji binarnych parami *i/

  • Jeśli funkcja może być naiwnie napisana, nikt z obu ostatnich sposobów nie jest odpowiedni.

    na przykład jeśli funkcja jest log , możesz po prostu zrobić:, sum(log(1:n))który reprezentuje:

    Sum(f(1:n));
    

    dla stosunkowo zaawansowanych funkcji, takich jak log(n)/x^n jakie możesz zrobić:

    Sum(log(1:n)./5.^(1:n))
    

    a nawet krótszy w niektórych przypadkach, gdy funkcja jest dłuższa jako f(x)=e^x+sin(x)*log(x)/x ...

    Sum(feval(@(y)e.^(y)+sin(y).*log(y)./y,1:n))
    

    jest to znacznie krótszy niż sum(feval(@(y)e.^(1:n)+sin(1:n).*log(1:n)./(1:n),1:n))


Uwaga: tę sztuczkę można zastosować w przypadku innych operatorów włącznie, takich jak prodlubmean


Abr001am
źródło