MATL - язык игры в гольф, созданный Луисом Мендо . MATL доказал свою высокую конкурентоспособность, часто опережая представления на других языках игры в гольф, таких как Pyth, CJam и Jelly.
Какие полезные советы для игры в гольф в MATL? (Как всегда, один совет за ответ, пожалуйста!)
- Для справки, MATL можно протестировать онлайн здесь .
- Документацию можно найти на Github
accumarray
(XQ
) может быть довольно мощным (возможно, даже больше, чем в MATLAB / Octave, поскольку у этих дескрипторов функций длины есть удобные числовые коды), но я не знаю этого достаточно хорошо, чтобы проиллюстрировать хорошими примерами. Если это действительно полезно, может ли кто-нибудь создать ответ с идеями о том, как его использовать?Ответы:
Знать предопределенные литералы
Хотя некоторые из них сохраняют информацию при копировании в буфер обмена, все они имеют предопределенное значение.
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
?1
, то4
,14
не будет делать. Тебе нужно1 4
. Или1K
сохранить один байтK
вместо4
удобен:1-4
означает: толкни1
, потом толкни-4
; тогда как1-K
означает: толкни1
, вычти из того, что внизу в стеке, а затем толкни4
&
Meta-Function (Alternative Input / Output Specification)Традиционный способ указать количество входных аргументов для передачи в функцию заключается в использовании
$
мета-функцииТочно так же, чтобы указать количество выходных аргументов, вы можете использовать
#
мета-функцию, указав количество выходных аргументов,или если вы передаете число, которое больше числа выходных аргументов , определенные для функции, только
mod(N, numberOfOutputs) + 1
выход подается.Вы можете дополнительно указать логический массив в качестве входных данных
#
для получения только определенных выходных аргументов.Все эти спецификации ввода / вывода удобны, но они очень быстро увеличивают количество байтов. Чтобы справиться с этим, MATL представил
&
мета-функцию в выпуске 17.0.0 . Эта&
мета-функция действует как ярлык для конкретной спецификации ввода или вывода для функции. Посмотрим, что это значит.В нашем примере выше мы хотели использовать версию с двумя входами
:
(создает вектор с одинаково расположенными значениями). Хотя число входных аргументов по умолчанию:
равно1
(создает массив из[1...N]
), очень часто пользователь хочет указать начальное значение диапазона, который требует второго ввода. Итак, для:
, мы определили,&
чтобы быть ярлыком для2$
.Теперь делается следующее, сохраняя байт !
Как мы можем определить, что такое альтернативное количество аргументов?
Спецификация ввода / вывода, которая
&
преобразуется в, зависит от конкретной функции, поэтому мы оптимизируем экономию байтов.Раздел аргументов ввода / вывода описания справки для каждой функции был обновлен, чтобы указать, каково это альтернативное количество входов / выходов (если есть). Возможное количество входных или выходных аргументов отображается в виде диапазона, а значения по умолчанию для каждого из них показаны в скобках. Спецификация ввода / вывода, которую можно заменить,
&
отображается после/
символа в скобках.Вот раздел ввода / вывода аргумента описания справки для
:
Как вы определили что
&
значит для каждой функции?Очень осторожно. Используя API StackExchange , мы смогли загрузить все ответы на MATL, которые когда-либо использовались в тесте PPCG. Анализируя каждый из ответов, мы смогли определить частоту, с которой каждая спецификация ввода / вывода использовалась для каждой функции. Используя эту информацию, мы смогли объективно определить спецификацию ввода / вывода, которую
&
мета-функция должна представлять для каждой функции. Иногда не было явного победителя, поэтому многие функции в настоящее время не&
определены.Вот скрипт, который мы использовали (к сожалению, он написан на MATLAB, а не на MATL).
А вот пример гистограммы из
$
/#
использованияисточник
&
собирался означать «увеличить количество входов на 1 по умолчанию». Его предложение оказалось гораздо более полезнымПознакомьтесь с истинными / ложными определениями MATL
Хотя
true
(T
) иfalse
(F
) ясно представляют результаты правдивости и ложности, соответственно, широко согласованное определение правдивости / ложности дает нам немного больше гибкости в MATL.Определение гласит:
Таким образом, мы можем написать быстрый тест на достоверность / ложность MATL, который будет проходить через все входные данные и отображать, были ли они признаны правдивыми или ложными
Вот онлайн версия.
Что это значит в MATL
На самом деле это означает, что в MATL (и, следовательно, в MATLAB и Octave) условие считается истинным, если оно непустое и действительные компоненты всех его значений отличны от нуля . Здесь есть две части, которые следует подчеркнуть.
Не ноль : это означает, что оно не равно нулю (
==
). Это включает в себя положительные числа, отрицательные числа, ненулевые символы и т. Д. Вы можете легко проверить, преобразовав данное значение вlogical
значение (g
) или вы можете использовать~~
Все значения : Обычно мы думаем о скалярах как об истинных или ложных, но в MATL мы можем оценивать скаляры, векторы строк, векторы столбцов или даже многомерные матрицы, и они считаются истинными тогда и только тогда, когда каждое отдельное значение ненулевой (как определено выше), иначе они ложные. Вот несколько примеров для демонстрации
Один крайний случай, как упомянуто выше, является пустым массивом
[]
, который всегда считается ложным ( пример )Как я могу использовать это для гольфа лучше?
Если в задаче просто упоминается, что ваш вывод должен быть правдивым или ложным, вы, вероятно, можете использовать приведенное выше определение, чтобы сбить несколько байтов с вашего ответа. Чтобы избежать путаницы, рекомендуется включить в свой ответ ссылку на онлайн-тест на достоверность / ложность, чтобы объяснить, как работают значения достоверности / ложности MATL.
Пара конкретных примеров:
Ответ, заканчивающийся на
A
. Если вызов требует truthy или falsy выход , и вы в конечном ответ вall
(A
) , чтобы создать скаляр, вы можете удалить эти последние байты и ваш ответ будет оставаться правильным (если выход не будет ,[]
так как[]
это ,false
но[]A
естьtrue
).Обеспечение того, чтобы массив содержал только одно уникальное значение : использует
&=
вместоun1=
. Если все значения в массиве равны, переданное поэлементное сравнение на равенство дастN x N
матрицу из всех. Если все значения не равны, эта матрица будет содержать некоторые0
значения и поэтому будет считаться ложной.источник
Неявный ввод
Большинство функций принимают некоторое количество ввода. Эти входные данные взяты из верхней части стека. Если вершина стека не содержит достаточно аргументов, он извлечет оставшийся аргумент из входных данных. (См. Раздел 7.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
, то есть выбрать все элементы массива).источник
Для петли размера n-1
Рассмотреть вопрос о замене
с
сохранить до целого байта или больше .
источник
@
/X@
в цикле или нет. Может быть, вы можете просто сказать «сохранить байты»Переместить вещи из цикла в цикл, чтобы использовать неявный конец
end
Операторы цикла ,,]
могут быть пропущены, если после них нет кода. Они заполняются синтаксическим анализатором MATL неявно.Так что, если вы можете переместить вещи из цикла в цикл, вы можете сохранить окончательный вариант.
]
.В качестве конкретного примера, следующий код находит, сколько концевых нулей в факториале числа
N
(см. Здесь ):1
кN
.5
присутствует.5
появляется (это работает, потому что для каждого5
есть по крайней мере один2
).Первая идея была
:"@Yf5=]vs
(обратите внимание, что после цикла есть операторы):Поскольку
v
по умолчанию объединяет все содержимое стека, его можно переместить в цикл. А так как сложение ассоциативно,s
его тоже можно перемещать. Это оставляет]
в конце кода, и, таким образом, его можно опустить:"@Yf5=vs
:источник
Более короткий способ определения пустого числового массива, если стек пуст
Чтобы вставить пустой числовой массив, вы обычно используете
[]
. Однако, если стек пуст, вы можете сохранить байт, используяv
. Эта функция по умолчанию объединяет все содержимое стека по вертикали, поэтому, если стек пуст, он создает пустой массив.Вы можете увидеть это в действии, например, здесь .
источник
Некоторые функции расширены по сравнению с 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 строк с таким количеством столбцов, сколько необходимо». Таким образом, результатом, в обоих случаях, является двумерный массивЧто-то вроде
reshape([10 20 30 40 50 60], 2, 2)
илиreshape([10 20 30 40 50 60], 5, [])
выдаст ошибку из-за несовместимых размеров. Тем не менее, MATL удалит элементы в первом случае ( попробуйте онлайн! ) Или заполнить нулями во втором ( попробуйте онлайн! ), Чтобы произвести, соответственно,и
Другие функции, которые имеют расширенные функциональные возможности по сравнению со своими аналогами MATLAB: (неисчерпывающий список)
S
(sort
),Yb
(strsplit
),m
(ismember
),h
(horzcat
),v
(vertcat
),Zd
(gcd
),Zm
(lcm
),YS
(circshift
),YA
(dec2base
),ZA
(base2dec
),Z"
(blanks
).источник
Получить индекс первого ненулевого элемента, если есть
f
Функция дает индексы всех ненулевых элементов массива. Часто вам нужен индекс первого ненулевого элемента. Это было быf1)
: применитьf
и выбрать свой первый элемент. Но если исходный массив не содержит ненулевое значение,f
будет выведен пустой массив ([]
), и попытка выбрать его первый элемент приведет к ошибке.Распространенным, более надежным требованием является получение индекса первого элемента, если есть хотя бы один , и в
[]
противном случае. Это может быть сделаноif
после веткиf
, но это дорого обходится. Лучший способ -fX<
применить минимальную функциюX<
к выводуf
.X<
возвращает пустой массив, когда его входные данные являются пустым массивом.Попробуйте онлайн! (Обратите внимание, что пустой массив вообще не отображается). Или посмотрите пример этого на работе здесь .
источник
Генерация диапазона до заданного массива
TL; WR : использовать
f
вместо,n:
если в массиве есть только ненулевые элементы.Часто бывает необходимо создать массив,
[1 2 ... L]
гдеL
указано количество элементов данного массива. Стандартный способ сделать этоn:
. Например, кодtn:*
принимает числовой вектор в качестве входных данных и вычисляет каждую запись, умноженную на ее индекс.Если данный массив гарантированно содержит только ненулевые записи (например, он образован положительными целыми числами или является строкой с печатными символами),
n:
его можно заменить наf
, который создает массив с индексами ненулевых записей. Таким образом, приведенный выше код становитсяtf*
, что сохраняет 1 байт.Еще несколько сложных примеров: 1 , 2 , 3 .
источник
Эффективное определение литералов числового массива
Вот несколько способов сохранения байтов при определении литералов числового массива. Ссылки даны на примеры ответов, которые их используют. Они были получены с использованием сценария аналитики созданного @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
использует кодовые точки символов для вычисления различий. Пример .источник