Поради щодо гольфу в Октаві


18

Які загальні поради щодо гольфу в Октаві? Я шукаю ідеї, які можна застосувати до проблем із гольфом взагалі, які принаймні дещо характерні для Octave (наприклад, "видалити коментарі" - це не відповідь). Будь ласка, опублікуйте одну пораду за кожну відповідь.


2
Пов’язані, але не дублікати: Поради щодо гольфу в MATLAB
Dennis Jaheruddin

Відповіді:


9
  1. Як тільки ви дізнаєтесь, aце вільне від нульових значень, використовуючи nnz(a)запчастини на 2 знаки порівняно з numel(a).
  2. Воліють a(a==0)в a(find(a==0)).
  3. ~tкоротше t==0і навіть ~~tкоротше t!=0.
  4. 0*(1:n) коротше, ніж zeros(1,n)
  5. Як правило, ||і &&, на відміну від багатьох інших операторів, масштабуйте результат, коли перший аргумент є скалярним. Для матриць логічне значення true має лише не порожні матриці без елементів, рівних нулю .

Отже, ми можемо робити 0||mзамість all(all(m))будь-якої матриці.

Спробуйте 0||[1 1;1 0]і 0||[1 1;1 1]переконаєте себе.

  1. Коли ви використовуєте вбудований кілька разів, зробіть функцію обробки, щоб запасні символи, наприклад. f=@find. Для коротких імен функцій принаймні 3 випадки виправдовують це, для довгих - навіть з двома випадками.

  2. Коли функція є одним оператором, віддавайте перевагу f=@(n)dosomething(n)нотації function r=f(n)r=dosomething(n);end.

  3. На жаль, глобальні змінні повинні бути оголошені як у глобальному масштабі, так і в кожній функції, використовуючи їх. Але є виняток: анонімні @(n)...функції "бачать" всі змінні з області, звідки вони викликані.

  4. Це можна зробити f(a=0,b=0)замість цього a=0;b=0;f(a,b).

  5. Це здається недокументованою особливістю, але порядок оцінювання знаходиться зліва направо (перевірено у zeros(a=n,b=a*a)версії 3.8.1), ви можете зробити як створити матрицю anxn ^ 2, так і зберегти номер рядка та стовпця у aта bзмінних.

  6. Таблиця пріоритету оператора - ваш друг. Не робіть, b=(a==0)оскільки b=a==0це те саме.


7

Я не пам'ятаю, в якому виклику я бачив, як це хтось використовує (будь ласка, скажіть нам =), але я знайшов це акуратним трюком:

Зазвичай, якщо ви додаєте матриці, ви повинні мати однаковий розмір, але для одновимірних (1xn і nx1) матриць є ярлик (який не працює в Matlab):

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

дає такий же ефект, як і

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

Тоді щось, про що вже згадував pawel.boczarski: В Octave ви можете (поки ви не можете в Matlab) визначати допоміжні змінні в межах функціональних ручок, а сам присвоєння змінної має значення присвоєння, щоб ви могли дійсно скоротити код (ну це марно приклад, але ви отримаєте хитрість):

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

Тоді інший трюк (також застосовний у Matlab) - це зловживання рядків для зберігання ( твердо кодованих ) номерів (цей акуратний трюк вкрадено з feersum) , вам просто потрібно щось, що інтерпретує рядок як число, що так само просто, як, наприклад, додавання нуля:

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

Або

sum('abc') == 294

Я вважаю, що це має бути a+0, ні a+'0'. Крім того, що поради хороші =)
Стюі Гріффін

Правильно, дякую! PS: Чи можете ви додати += -= /=нижче операторів у свій список?
недолік

1
+aкоротшеa+0
Луїс Мендо

7

Використання списку аргументів:

Octave здатний отримати аргументи за замовчуванням, тому вирази можна оцінити в списку аргументів.

Ця функція корисна, коли ми хочемо обчислити вираз і використовувати його кілька разів:

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

Один випадок використання - це коли ми використовуємо індексоване призначення для зміни частини масиву, і ми хочемо використовувати масив:

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

Але вираз (a(2)=5)повертається a(2), або вираз (a([1 3])=4)повертає масив двох елементів. Жоден з них не повертає весь масив. Ми можемо використовувати список аргументів:

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

Тут результат індексованого призначення зберігається в фіктивній змінній bі функція повертає масив.


6

-У Octave можна застосувати індексацію на тимчасовий вираз, функцію, заборонену в MATLAB, і ця функція дуже корисна для гри в гольф. приклад:

Октава: [1 23 4 5 7](3:4) і його еквівалент MATLAB: a=[1 23 4 5 7];a(3:4)
Октава: hilb(4)(4:5,4:5) і його еквівалент MATLAB: h=hilb(4);h(4:5,4:5)
Октава: {1,4,{4 5 6},[7 ;3]}{3}і його еквівалент MATLAB: a={1,4,{4 5 6},[7 ;3]};a{3}
Октава: num2cell([1 2 3 4]){:}для створення списку, розділеного комами
Октава:a'(:)'

-Іноді в анонімній функції в якості звичайної функції нам потрібно оцінити кілька виразів, які включають призначення. Один підхід полягає в тому, що ми можемо розмістити кожен вираз у комірці (оскільки клітина може містити об'єкт декількох типів) і коли нам потрібно значення кожного виразу ми можемо використовувати індексацію для вилучення цього елемента.

{1,4,{4 5 6},[7 ;3]}{3}
або

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


@StewieGriffin Приємна порада! Відповідь оновлено!
rahnema1

5

Пропустіть крапки з комою!

Я використаю цю відповідь, щоб проілюструвати суть.

Початковий код:

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

Після видалення крапки з комою, його можна зменшити до наступного, зберігаючи три байти:

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

Це може бути використано досить багато місць, і речі, які ви навіть не намагаєтеся, тому що схоже, що синтаксична помилка часто працює.


1
речі, які ви навіть не намагаєтеся, бо схоже на помилку синтаксису часто працює Октава в двох словах
Санчіз

2

Це проста, але корисна.

У Octave, але не у MATLAB, ви можете робити так, як у C ++:

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

2

Ще одна проста, але корисна (не можлива в MATLAB):

Призначте одне і те ж значення кільком змінним:

a=b=c=0;

2

Використовуйте eval!

Натхненний відповідь Луїс Mendo в тут .


Анонімні функції в більшості випадків коротші, ніж створення сценарію, для якого потрібен один або більше дзвінків input(''). Мінус полягає в тому, що петлі та змінні модифікації (наприклад, заміна двох елементів у матриці) неможливо громіздко.

З eval, ви можете отримати вхід, як і у звичайній анонімній функції, та запустити сценарій, як у звичайному сценарії:

Врахуйте це :

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

У порівнянні з цим:

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

Код ідентичний, але вхідний розділ значно коротший.


Це також можна використовувати для зміни вхідних змінних, таких як ця (заслуга Луїса Мендо !):

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

3
Код ідентичний Тільки негарніше, повільніше та менш читабельний. Що ще можна попросити? :-D
Луїс Мендо


1

Пов’язані, але не ідентичні поради щодо MATLAB .

Маловідомою і мало використовуваною функцією Octave є те, що більшість вбудованих функцій можна назвати без дужок, і в цьому випадку вони будуть розглядати все, що слідує за нею, як рядок (доки він не містить пробілів). Якщо він містить пробіли, вам потрібні лапки. Це часто можна використовувати для збереження байта або двох під час використання disp. Всі наступні роботи і дають однаковий результат:

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

Якщо у вас є пробіли, ви повинні мати лапки:

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

Інші, менш корисні приклади включають:

nnz PPCG
ans = 4

size PPCG
ans = 1  4

str2num 12
ans = 12
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.