Поради щодо гольфу в MATL


20

MATL - мова для гольфу, створена Луїсом Мендо . MATL виявився дуже конкурентоспроможним, часто перемагаючи подання іншими мовами для гольфу, такими як Pyth, CJam і Jelly.

Які корисні поради щодо гольфу в MATL? (Як завжди, будь-яка порада на відповідь, будь ласка!)


5
Це, безумовно, велика перевага, якщо ви знаєте деякі Matlab / Octave. Деякі прийоми з Поради щодо гольфу в Matlab та Поради щодо гольфу в Octave використовуються і в MATL.
flawr

Пропозиція: схоже, що accumarray( XQ) може бути досить потужним (можливо, навіть більше, ніж у MATLAB / Octave, оскільки ці ручки функцій довжини мають зручні числові коди), але я не знаю цього досить добре, щоб проілюструвати хорошими прикладами. Якщо це насправді корисно, чи може хтось створити відповідь із ідеями, як ним користуватися?
sundar

Відповіді:


7

Знайте попередньо визначені літерали

Хоча деякі з них зберігають інформацію при копіюванні в буфер обміну, всі вони мають заздалегідь задане значення.

  • F, натискає 0 (насправді помилково )
  • T, натискає 1 (насправді вірно )
  • H, натискання 2 (попередньо визначене значення буфера обміну)
  • I, натискання 3 (попередньо визначене значення буфера обміну)
  • K, натискання 4 (попередньо визначене значення буфера обміну)
  • J, натискає 0 + 1j (попередньо визначене значення буфера обміну)

Не впевнений, чи я покрив усі заздалегідь задані значення.


Просто для повноти (і якщо ви хочете додати свою відповідь): кожен рівень буфера обміну Lтакож має заздалегідь задане значення, але вони призначені для спеціального використання (а не загальних загальних значень). Наприклад, 1Lдає [1 0](що використовується як індекс 1:end), 2Lдає [0 -1 1](для 1:-1:end). Крім того , функції lі Oприймати 0 входи за замовчуванням і продукції 0і 1відповідно
Luis Mendo

Я не бачу, як це корисно ... Не можу я просто написати 4?
Cyoce

@Cyoce Корисність полягає у тому, щоб уникнути місця як роздільника. Якщо ви хочете натиснути 1, значить 4, 14не вийде. Вам знадобиться 1 4. Або 1Kзберегти один байт
Луїс Мендо

@LuisMendo ах, бачу. Напевно, я припускав, що він використовує метод лише 1-значний номер (не впевнений, чому)
Cyoce

1
Інший випадок, коли Kзамість 4зручного є: 1-4означає: натиснути 1, потім натиснути -4; тоді як 1-Kозначає: натиснути 1, відняти все, що внизу в стеці, а потім натиснути4
Луїс Мендо

5

&Meta-Function (Alternative Input / Output Specification)

Традиційний спосіб визначення кількості вхідних аргументів для передачі функції - це використання $мета-функції

2$:     % Two-input version of :

Аналогічно, для визначення кількості вихідних аргументів ви можете використовувати #мета-функцію із зазначенням або кількості вихідних аргументів,

2#S     % Two-output version of sort

або якщо ви передаєте число, яке більше числа вихідних аргументів , певні для функції, тількиmod(N, numberOfOutputs) + 1 вихід подається.

4#S     % Get only the second output of sort

Ви можете додатково вказати логічний масив як вхід #для отримання лише конкретних вихідних аргументів.

TFT#u   % Three output version of unique and discard the second output

Усі ці вхідні / вихідні характеристики є зручними, але вони швидко збільшують кількість байтів. Щоб впоратися з цим, MATL ввів &метафункцію в релізі 17.0.0 . Ця &метафункція діє як ярлик для певного входу або виходу специфікації для функції. Подивимось, що це означає.

У нашому прикладі вище ми хотіли скористатися двовхідною версією :(створює вектор з однаково розташованими значеннями). Незважаючи на те, що типовим числом вхідних аргументів :є 1(створює масив з [1...N]), дуже часто користувач бажає вказати початкове значення діапазону, який вимагає другого введення. Отже :, ми визначили, &що це ярлик для 2$.

10      % Push 10 to the stack
12      % Push 12 to the stack
2$:     % Create an array: [10, 11, 12] 

Тепер стає наступним, зберігаючи байт !

10 12 &:

Як ми можемо визначити, що таке альтернативна кількість аргументів?

Специфікація вводу / виводу, що &перекладається, є функціональною , що оптимізує економію байтів.

Розділ аргументу введення / виводу опису довідки для кожної функції оновлено, щоб вказати, що таке альтернативна кількість входів / виходів (якщо вони є). Можлива кількість аргументів введення або виводу відображається у вигляді діапазону, а значення за замовчуванням для кожного відображаються в дужках. Специфікація вводу / виводу, яку можна замінити &, відображається після /символу в дужках.

Ось розділ аргументу введення / виводу опису довідки для :

 +- Min-Max range of # of inputs
 |        +----- Alt. Default # of inputs
 |        |
 V        V
1--3 (1 / 2); 1 <--- Possible / Default # of outputs
      ^       
      |       
  Default # of inputs

Як ви визначили, що &означає для кожної функції?

Дуже обережно. Використовуючи API StackExchange , ми змогли завантажити всі відповіді MATL, які коли-небудь використовувались у виклику PPCG. Проаналізувавши кожну з відповідей, ми змогли визначити частоту, з якою використовується кожна специфікація вводу / виводу для кожної функції. Використовуючи цю інформацію, ми змогли об'єктивно визначити специфікацію вводу / виводу, яку &мета-функція повинна представляти для кожної функції. Іноді не було чіткого переможця, тому багато функцій на даний момент не &визначено.

Ось сценарій, який ми використовували (на жаль, він написаний у MATLAB, а не в MATL).

А ось приклад гістограми з $/ #використання


1
Цю функцію запропонував @Suever. Спочатку &малося на увазі "збільшити кількість входів на 1 щодо типових". Його пропозиція виявилася набагато кориснішою
Луїс Мендо

5

Ознайомтеся з правдивими / хибними визначеннями MATL

Тоді як true( T) та false( F) чітко представляють правду та хибність, відповідно, широко узгоджене визначення truthy / falsy дає нам трохи більше гнучкості в MATL.

У визначенні зазначено:

if (x)
    disp("x is truthy");
else
    disp("x is falsy");
end

Таким чином, ми можемо скласти швидкий тест на MATL truthy / falesy, який буде проходити через всі входи та показувати, чи вважали вони правдою чи хибністю

` ? 'truthy' } 'falsey' ]DT

Ось онлайн-версія.

Що це означає в MATL

Що це насправді означає MATL (і, отже, у MATLAB та Octave), це те, що умова вважається істинною, якщо вона не порожня, а реальні компоненти всіх її значень ненульові . До цього слід наголосити дві частини.

  1. Ненульовий : Це означає саме те, що не дорівнює нулю ( ==). Сюди входять позитивні числа, від’ємні числа, ненульові символи тощо. Ви можете легко перевірити, перетворивши задане значення у logicalзначення ( g) або можете використовувати~~

    F           % Falsy
    T           % Truthy
    0           % Falsy
    1           % Truthy
    2           % Truthy
    -1          % Truthy
    'a'         % Truthy
    ' '         % Truthy (ASCII 32)
    char(0)     % Falsy  (ASCII 0)  
    
  2. Усі значення : Зазвичай ми вважаємо скаляри істинними або хибними, але в MATL ми можемо оцінювати скаляри, вектори рядків, вектори стовпців або навіть багатовимірні матриці, і вони вважаються правдивими, якщо і лише якщо кожне значення не нульові (як визначено вище), інакше вони хибні. Ось кілька прикладів для демонстрації

    [1, 1, 1]           % Truthy
    [1, 0, 0]           % Falsey
    [1, 1, 1; 1, 1, 1]  % Truthy
    [1, 0, 1; 1, 1, 1]  % Falsey
    'Hello World'       % Truthy
    

Як було сказано вище, один крайній випадок - це порожній масив [], який завжди вважається хибним ( приклад )

Як я можу це краще використовувати для гольфу?

Якщо у виклику просто згадується, що ваш результат повинен бути неправдивим або хибним, ви, швидше за все, скористаєтесь вищевикладеним визначенням, щоб поголити кілька байтів своєї відповіді. Щоб зберегти плутанину, рекомендується включити у відповідь посилання на онлайн-тест на фальшивість / хибність, щоб допомогти пояснити, як працюють значення MATL truthy / false.

Кілька конкретних прикладів:

  • Відповідь, що закінчується на A. Якщо для виклику потрібен надійний або хибний результат, і ви закінчите свою відповідь в all( A), щоб створити скаляр, ви можете видалити цей останній байт, і ваша відповідь залишиться правильною (якщо вихідний []з тих пір []є, falseале []Aє true).

  • Переконайтеся, що масив містить лише одне унікальне значення : Використовується &=замість un1=. Якщо всі значення масиву рівні, то порівняння рівності, що транслюється в елементі, дасть N x Nматрицю всіх. Якщо всі значення не рівні, ця матриця буде містити деякі 0значення і тому вважатись хибною.


4

Неявне введення

Більшість функцій приймає деяку кількість вводу. Ці входи беруть у верхній частині стека. Якщо верхня частина стека не містить достатньої кількості аргументів, вона виведе решту аргументів із вхідних даних. (Дивіться розділ 7.3 в документації) Я хочу навести первісне пояснення:

Неявні входи можна розглядати так: стек нескінченно розширюється внизу, тобто в позиціях 0, −1, −2, ... зі значеннями, які спочатку не визначені, але вирішуються в ходу шляхом неявного введення . Ці дані запитуються у користувача лише тоді, коли вони потрібні, в тому порядку, в якому вони потрібні. Якщо одночасно потрібно декілька входів, вони дотримуються звичайного порядку стеку, тобто вхід, який є найглибшим у (розширеному) стеку, вводиться першим.


2
Неявне введення - це функція, яку запропонував @flawr
Луїс Мендо

6
@flawr повинен бути справді розумним хлопцем. : D
недолік

3

Логічні масиви часто можна використовувати як числові масиви

Ви часто можете використовувати TFпозначення " " замість матриць прямолінійних нулів та одиниць. Наприклад, FTFте саме [0,1,0], що FTFстворює logicalзначення, а не doubleзначення. Зазвичай це не є проблемою, оскільки будь-яка арифметична операція розглядає логічні значення як числа. Наприклад, FTFQдає [1,2,1]( Qє "збільшення на 1").

У деяких випадках перетворення числа в двійкове може бути коротшим. Так , наприклад, [1,0,1], TFTі 5Bє однаковими; знову з обережністю, що останні два є logicalзначеннями.


Випадок, коли різниця між TF(логічним) та [1 0](числовим) значеннями є при використанні в якості індексів. Масив типу, який logicalвикористовується як індекс, означає: вибирати відповідні елементи T, відкинути ті, що відповідають F. Таким чином [10 20]TF)виробляє 10(виберіть перший елемент), тоді як [10 20][1 0])виробляє [10 20](індекс [1 0]має інтерпретацію 1:end, тобто виберіть усі елементи масиву).


3

Для петлі розміром n-1

Подумайте про заміну

tnq:"...

з

td"...

щоб зберегти до цілого байта або більше .


@Luis правда! Я думав, що може знадобитися оригінальний вектор, який перебуває в циклі, але це неможливо і при першому підході. Вилучимо це зауваження.
Санчіз

Але вам не обов'язково зберігати 1 байт; ви економите 1 або 2 залежно від того, вам потрібно @/ X@в циклі чи ні. Можливо, ви можете просто сказати "зберегти байти"
Луїс Мендо

3

Перемістіть речі після циклу до циклу, щоб використовувати неявний кінець

endВисловлювання циклу ], може бути залишене, якщо після них немає коду. Вони заповнюються аналізатором MATL неявно.

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

В якості конкретного прикладу, наступний код визначає, скільки кінцевих нулів є у факторіалі числа N(див. Тут ):

  • Код циклу від 1до N.
  • Для кожного з цих чисел він обчислює основні коефіцієнти і визначає, скільки разів 5присутній.
  • Відповідь - накопичена кількість разів 5з’являється (це працює, тому що для кожного 5є принаймні одне 2).

Перша ідея була :"@Yf5=]vs(зауважте, що після циклу є заяви):

:      % Range from 1 to implicit input
"      % For each number in that vector
  @    %   Push that number
  Yf   %   Vector of prime factors (with repetitions)
  5=   %   True for entries that equal `5`, and `false` for the rest
]      % End for
v      % Concatenate all vectors as a column vector
s      % Sum. Implicitly display

Оскільки vза замовчуванням об'єднує весь вміст стеку, його можна перемістити у цикл. А оскільки додавання є асоціативним, sйого можна також перемістити. Це залишає ]в кінці коду, і таким чином його можна опустити :"@Yf5=vs:

:      % Range from 1 to implicit input
"      % For each number in that vector
  @    %   Push that number
  Yf   %   Vector of prime factors (with repetitions)
  5=   %   True for entries that equal `5`, and `false` for the rest
  v    % Concatenate all vectors so far as a column vector
  s    % Sum. Inplicitly end loop and display

Я не знаю ні копійки цієї ієрогліфічної писемної мови, але я зарезервую значну частину свого часу, вивчаючи її, можливо, наступні три місяці.
13001

@ Agawa001 :-) Ви побачите, що це дуже схоже на Matlab. Ви також можете запитати або прокоментувати тут
Луїс Мендо

3

Коротший спосіб визначення порожнього числового масиву, якщо стек порожній

Щоб натиснути порожній числовий масив, який ви зазвичай використовуєте []. Однак якщо стек порожній, ви можете зберегти байт за допомогою v. Ця функція за замовчуванням об'єднує весь вміст стека вертикально, тому якщо стек порожній, він створює порожній масив.

Ви можете побачити його в дії, наприклад, тут .


2

Деякі функції розширено порівняно з MATLAB або Octave

Якщо ви родом з MATLAB або Octave, ви знайдете багато функцій MATL, подібних до функцій на цих мовах. Але в досить багатьох з них функціонал розширений.

Як приклад, розглянемо reshapeфункцію MATLAB , якій у MATL відповідає e. Фрагменти коду reshape([10 20 30 40 50 60], 2, 3)і reshape([10 20 30 40 50 60], 2, [])відповідно означають "переформатувати вектор рядка [10 20 30 40 50 60в матрицю 2 × 3", або "в 2-рядову матрицю з стільки стовпців, скільки потрібно". Таким чином, результат в обох випадках - 2D масив

10    30    50
20    40    60

Щось на кшталт reshape([10 20 30 40 50 60], 2, 2)або reshape([10 20 30 40 50 60], 5, [])призведе до помилки через несумісні розміри. Однак MATL видалить елементи в першому випадку ( спробуйте в Інтернеті! ) Або заповнить нулями у другому ( спробуйте в Інтернеті! ), Щоб створити, відповідно,

10 30
20 40 

і

10 60
20  0
30  0
40  0
50  0

Іншими функціями, які мають розширену функціональність порівняно зі своїми аналогами MATLAB, є (неповний список) S( sort), Yb( strsplit), m( ismember), h( horzcat), v( vertcat), Zd( gcd), Zm( lcm), YS( circshift), YA( dec2base), ZA( base2dec), Z"( blanks).


1

Отримайте індекс першого ненульового елемента, якщо такий є

fФункція дає індекси всіх ненульових елементів масиву. Часто потрібен індекс першого ненульового елемента. Це було б f1): застосуйте fта виберіть його перший елемент. Але якщо вихідний масив не містить жодного ненульового значення, fвиведе порожній масив ( []), а спроба вибрати його перший елемент призведе до помилки.

Загальною, більш надійною вимогою є отримання індексу першого елемента, якщо він є хоча б одним , []інакше. Це можна зробити за допомогою ifгілки після f, але це байтово дорого. Кращий спосіб - fX<це застосувати мінімальну функцію X<до виходу f. X<повертає порожній масив, коли його вхід - порожній масив.

Спробуйте в Інтернеті! (Зверніть увагу, що порожній масив взагалі не відображається). Або дивіться приклад цього на роботі тут .


1

Створіть діапазон до тих пір, як заданий масив

TL; WR : використовувати fзамість того, n:якщо в масиві є лише ненульові елементи.


Часто буває так, що потрібно генерувати масив, [1 2 ... L]де Lкількість елементів даного масиву. Стандартний спосіб зробити це n:. Наприклад, кодtn:* приймає числовий вектор як вхідний і обчислює кожен запис, помножений на його індекс.

Якщо даний масив гарантовано містить лише ненульові записи (наприклад, він утворений додатними цілими числами, або це рядок з друкованими символами), n:його можна замінити f, який виробляє масив з індексами ненульових записів. Так стає вищевказаний код tf*, який зберігає 1 байт.

Ще кілька детальних прикладів: 1 , 2 , 3 .


1

Ефективне визначення числових літералів масиву

Ось кілька способів, які можна використовувати для збереження байтів при визначенні числових літералів масиву. Посилання наведені на приклади відповідей, які їх використовують. Вони отримані за допомогою сценарію аналітики, створеного @Suever .

Сполучення та заздалегідь задані літерали

Для масивів з малим числом іноді можна використовувати конкатенацію (функцію hі v), а також зумовлені літерали , щоб уникнути використання прогалин в якості роздільників: порівняти [2 4], 2 4hі 2Kh, всі з яких визначає масив [2 4]. Точно так само 2K1vз порожнім стеком визначається [2; 4; 1]. Приклад .

Літери в числових літералах масиву

Для дещо більших чисел ви можете заощадити пробіли, використовуючи той факт, що деякі літери мають числові значення в прямолінійному масиві. Тож замість [3 5 2 7;-4 10 12 5]вас можна використовувати [IAHC;dX12A]. Приклад .

Зокрема, у літералі масиву,

  • O, l, H I KМають свої звичайні значення 0, ...,4
  • A, ..., Eзначить 5, ...,9
  • X засоби 10
  • a, ... dозначає -1, ...,-4
  • Jі Gозначають 1jі-1j
  • P засоби pi
  • Y засоби inf
  • Nзасоби NaN.

Строкові та послідовні відмінності

Для більших чисел dможе допомогти визначення рядка та обчислення його послідовних відмінностей (з ): замість цього [20 10 35 -6]ви можете використовувати '!5?b\'d. Це працює, оскільки dвикористовує кодові точки символів для обчислення різниць. Приклад .

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