Советы по игре в гольф в Октаве


18

Какие общие советы у вас есть для игры в гольф в Октаве? Я ищу идеи, которые могут быть применены к кодовым проблемам гольфа в целом, которые хотя бы несколько специфичны для Octave (например, «удалить комментарии» - это не ответ). Пожалуйста, оставьте один совет за ответ.


2
Связанные, но не дубликаты: Советы по игре в гольф в MATLAB
Деннис Джаэруддин

Ответы:


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. Это кажется недокументированной функцией, но порядок оценки слева направо (проверено в v. 3.8.1), вы можете сделать, zeros(a=n,b=a*a)чтобы создать матрицу тревог ^ 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: Не могли бы вы добавить += -= /=операторов etc в ваш список ниже?
Flawr

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, и эта функция очень полезна для игры в гольф. пример:

Octave: [1 23 4 5 7](3:4) и эквивалент MATLAB: a=[1 23 4 5 7];a(3:4)
Octave: hilb(4)(4:5,4:5) и эквивалент MATLAB: h=hilb(4);h(4:5,4:5)
Octave: {1,4,{4 5 6},[7 ;3]}{3}и эквивалент MATLAB: a={1,4,{4 5 6},[7 ;3]};a{3}
Octave: num2cell([1 2 3 4]){:}для создания списка, разделенного запятыми
Octave: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
вещи, которые вы даже не пытаетесь, потому что похоже, что синтаксическая ошибка часто работает в двух словах
Octave

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!

Вдохновленный ответом Луиса Мендо здесь .


Анонимные функции в большинстве случаев короче, чем создание сценария, для которого требуется один или несколько вызовов 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.