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ź.



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)

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 :)


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.


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


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 .


Ś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.

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 .


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').


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;

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

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)

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


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.