Советы по игре в гольф в MATL


20

MATL - язык игры в гольф, созданный Луисом Мендо . MATL доказал свою высокую конкурентоспособность, часто опережая представления на других языках игры в гольф, таких как Pyth, CJam и Jelly.

Какие полезные советы для игры в гольф в MATL? (Как всегда, один совет за ответ, пожалуйста!)


5
Это определенно большое преимущество, если вы знаете немного Matlab / Octave. Некоторые трюки из Tips для игры в гольф в Matlab и Tips для игры в гольф в 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соответственно
Луис Мендо

Я не понимаю, как это полезно ... Разве я не могу просто написать 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) ясно представляют результаты правдивости и ложности, соответственно, широко согласованное определение правдивости / ложности дает нам немного больше гибкости в MATL.

Определение гласит:

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

Таким образом, мы можем написать быстрый тест на достоверность / ложность MATL, который будет проходить через все входные данные и отображать, были ли они признаны правдивыми или ложными

` ? '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.

Пара конкретных примеров:

  • Ответ, заканчивающийся на A. Если вызов требует truthy или falsy выход , и вы в конечном ответ в all( A) , чтобы создать скаляр, вы можете удалить эти последние байты и ваш ответ будет оставаться правильным (если выход не будет , []так как []это , falseно []Aесть true).

  • Обеспечение того, чтобы массив содержал только одно уникальное значение : использует &=вместо un1=. Если все значения в массиве равны, переданное поэлементное сравнение на равенство даст N x Nматрицу из всех. Если все значения не равны, эта матрица будет содержать некоторые 0значения и поэтому будет считаться ложной.


4

Неявный ввод

Большинство функций принимают некоторое количество ввода. Эти входные данные взяты из верхней части стека. Если вершина стека не содержит достаточно аргументов, он извлечет оставшийся аргумент из входных данных. (См. Раздел 7.3 в документации). Я хотел бы привести оригинальное объяснение:

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


2
Неявный ввод - это функция, предложенная @flawr
Луис Мендо

6
@flawr должен быть действительно умный парень. : D
flawr

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

сохранить до целого байта или больше .


@ Это правда! Я подумал, что может понадобиться исходный вектор, который зацикливается, но это невозможно и в первом подходе. Уберу это замечание.
Санчиз

Но вы не обязательно сохраняете 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

Я не знаю ни копейки этого иероглифически-подобного письменного языка, но я, возможно, зарезервирую большую часть своего времени, изучая его в следующие три месяца.
Abr001am

@ 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 строк с таким количеством столбцов, сколько необходимо». Таким образом, результатом, в обоих случаях, является двумерный массив

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.