Какие общие советы у вас есть для игры в гольф в Луа? Я ищу идеи, которые могут быть применены к кодовым проблемам гольфа в целом, которые, по крайней мере, несколько специфичны для Lua (например, «удалить комментарии» - это не ответ). Пожалуйста, оставьте один совет за ответ.
21
Ответы:
В дополнение к уже опубликованным, вот некоторые уловки, которые я собрал со временем, без определенного порядка ...
Для вызовов функций, которые имеют только один параметр, разделенный символом (
"
для строк,{
для таблиц), параметр не нужно заключать в круглые скобки.Например, вместо того, чтобы делать
print("hello")
, вы можете просто сделать:print"hello"
Удалите как можно больше пробелов - это особенно легко сделать после символа, который закрывает строки (или перед одним открытием), вызовов функций, таблиц ...
Вместо этого
print(42) a=1
вы можете это сделатьprint(42)a=1
. Другой пример:print(a and-1 or-2)
.Используйте троичный оператор, когда можете! Вместо того
if a>0 then print("hello") else print("goodbye") end
, чтобы предпочестьprint(a>0 and "hello" or "goodbye")
. Больше информации здесь .(Это действительно может стать еще лучше:
print(a>0 and"hello"or"goodbye")
)Используйте синтаксический сахар при вызове двоеточия, когда можете: вместо
string.rep(str,12)
, делайтеstr:rep(12)
. Это также работает с переменными (и только так):("a"):rep(5)
Вместо того, чтобы
tonumber(str)
просто делатьstr+0
Для функций без параметров вместо определения их обычным способом (
function tick() blabla() end
) вы можете сделать:,ticks=loadstring"blabla()"
которая сохраняет 1 или более байтов в зависимости от содержимого. Кроме того, если вы определите несколько функций, локализуйте ихloadstring
до переменной с 1 символом, и вы сэкономите много байтов;). Кредиты Джиму Бовенсу за этот трюк.Lua считает пустую строку (и в
0
отличие от других языков) истинной в условных тестах, поэтому, например, вместо выполненияwhile 1 do ... end
сохраните 1 байт, написавwhile''do ... end
источник
str+0
эквивалент~~str
, может быть полезным для его приоритетаЯ уже думал об одном. Я не знаю, работает ли он на некоторых других языках, но я знаю только Lua, который позволяет хранить функции в переменных. Так что если например
string.sub
используется в вашей программе несколько раз, используйте напримерs=string.sub
.источник
s=("").sub
илиs=a.sub
для любой переменной,a
содержащей строковое значение.Это довольно многословный язык для игры в гольф ... но некоторые общие советы, которые приходят на ум:
if
...then
...else
...end
это большая трата.for i=1,5 do
.#
Оператор является довольно большим для игры в гольф (и в целом).источник
Укороти свой бесконечный цикл
Когда вам нужно использовать бесконечный цикл, вы можете подумать об использовании a
while
, но вместо этого использование метки короче на 2 байта:Используйте как можно меньше места
Есть простая вещь, которую вы можете (ab) использовать, чтобы убрать еще больше пробелов из вашего кода. Спецификации Lua ясны в отношении имени, которое вы даете переменным: они должны начинаться с буквы. Это означает, что иногда вы можете пропустить пробелы между числами и функциями / переменными
Возможность удаления пробела зависит от буквы после числа, вот письмо, которое не позволит вам сделать это:
Используя это и обращая внимание на то, как вы называете свои переменные, вы можете сделать большую часть ваших исходных кодов свободными.
Взяв пример уже здесь и используя этот совет, вот еще один байт, который вы можете сбрить :).
Используйте правильный метод ввода
Если мы посмотрим на шаблон и стоимость для каждого основного типа ввода, вот что мы имеем:
Каждый из этих методов позволяет нам брать 1 вход, причем функция является самой дорогой (но позволяет нам брать таблицу в качестве входных данных).
Теперь мы можем видеть, что использование аргумента командной строки - это путь, если вы хотите играть в гольф, но помните: он может быть еще короче
Они
...
немного особенные в lua, это переменная, содержащая распакованное содержимоеarg
или распакованные параметры в случае функции с переменным числом аргументов.Когда вам нужно получить более одного ввода и использовать каждый из них, может быть полезно сохранить их в переменной. Вот несколько способов сохранить 2 входа в переменных
и вот самый короткий вызов, который вы могли бы сделать без переменных:
С момента, когда у вас есть 3 аргумента, или когда вы используете 2 аргумента, причем один используется дважды, вы уже получаете байты из-за
a,b=...
! :)Почти никогда не использовать, если!
Практически нет случаев, когда использование оператора if / elseif / if будет стоить меньше, чем троичный. шаблон для такого заявления действительно тяжел:
На простом примере вы уже сохраняете 12 байтов, когда вам приходится делать какие-то другие операции, это становится все более и более важным, так что имейте это в виду!
Кроме того, троицы в lua являются особыми , есть некоторые условия, как они работают, для тех, кто заинтересован, я объясню это ниже:
Тройки в Луа имеют форму
<condition> and <case true: have to be a true value> or <case false: can be anything>
Прежде всего, давайте посмотрим на таблицу истинности
or
. Aor
можно рассматривать как функцию: она всегда возвращает значение, вот значение, которое она возвращает:Вот что позволяет нам строить нашу троицу.
Это
and
то, что позволяет нам оценить условие, оно всегда будет возвращаться,y
еслиx and y
оценивается как истинное.Проблема в том, что он потерпит неудачу, если мы хотим, чтобы
nil
илиfalse
было возвращено, когда условиеfalse
. Например, следующее всегда будет возвращать 5, несмотря на то, что условие истинно.Вот пошаговая оценка троичного, чтобы объяснить, как он работает (это будет полезно, когда вам придется их вкладывать :))
источник
Я также собрал несколько советов. Я уверен, что некоторые из моих совпадут с уже заявленными, но я все равно включу их в основу создания более полного ответа.
Присвойте повторяющиеся функции переменным
Lua позволяет назначать функции переменным. Ещё одна символьная переменная. Это означает, что если вы повторите функцию
string.sub(x, y)
более двух раз, вы получите выгоду от назначения ее переменной.Без присвоения переменной (69 символов):
Присвоение переменной (51 символ):
Есть случаи, когда вы можете сделать еще один шаг вперед. Lua позволяет ООП манипулировать строками, например так:
str:sub(x, y)
илиstr.sub(x, y)
Это открывает новые опции для нашего кода. Вы можете назначить переменную функции по ее ссылке, как показано (46 символов.)Используйте самый эффективный способ разбора строк
Вы можете использовать
for
цикл иstring.sub
выполнять итерацию за символом в Lua. Иногда это может работать лучше всего, в зависимости от ваших потребностей, но в других случаях string.gmatch будет работать с меньшим количеством символов. Вот пример обоих:И когда игра в гольф, разница более заметна:
Назначение реструктуризации для оптимизации пробелов
В Lua вам не нужно ставить пробел между закрытыми скобками или конечной кавычкой и следующим символом. До сих пор я обнаружил два случая, когда реструктуризация с учетом этого будет сокращать персонажей.
Назначение переменных:
Если заявления:
Верните как можно меньше символов
Если вы должны вернуть значение «истина» или «ложь», то, похоже, вы должны обязательно использовать как минимум 5 символов для возвращаемого значения. На самом деле следующее работает так же хорошо:
источник
nil
иfalse
оценивается как ложное в lua, все остальное верно, поэтому ваши советы о заменеx==0
,x==""
иx==''
наx
ложное. Я в настоящее время изменяю это наnil
:).Это только Lua (я думаю) оптимизация:
Строки автоматически преобразуются в числа при выполнении арифметических операций над ними. Просто следите за условными утверждениями, они не конвертируются автоматически. Это отлично подходит для принятия пользовательского ввода в виде чисел при экономии места.
Переключение содержимого двух переменных не требует временной переменной.
a,b=b,a
поменяет местами значения a и b.Кроме того, чтобы расширить сказанное выше, любой буквенно-цифровой символ может касаться не буквенно-цифрового символа. Так
a,b=io.read():match"(.+)/(.+)"u,v=a,b
что это идеальный, рабочий сценарий, даже при отсутствии пробелов.источник
Объединить присвоения локальных переменных
Вместо того:
Используйте параллельное назначение:
6 байтов сохранено для каждой переменной!
Объявление локальных переменных через неиспользуемые параметры функции
Вместо того:
использование
6 байтов сохранено (минус 1-2 байта для каждой переменной, которая может быть дублирована).
источник
local
оправдано при игре в гольф, потому что вы просто должны использовать другое имя. Мы могли бы использовать ВСЕ имена до 7 символов и таблицы со строковыми индексами до 7 комбинаций символов, прежде чем мы добьемся того, что могло бы принести пользу от использования местных жителейVariadic Функции
Основная переменная функция, которая вас беспокоит, это
print()
. Например, когда вы используете его вместе,String.gsub()
он напечатает строку, которую вы изменили, и количествоgsub
срабатываний.Чтобы подавить этот второй вывод, заключите его
gsub
в parens, чтобы заставить его возвращать только одно значениеисточник
Знать, как выводить
Есть два основных способа вывода в lua
Когда вам приходится конкатенировать несколько раз, вы можете сократить это, используя
io.write()
присвоенную однобуквенной переменной вместо стандартного оператора конкатенации..
Вы получаете 2 байта за каждый звонок, платя при этом авансом
Вы даже на третьем объединении, и начинаете получать байт на четвертом.
источник
print
и неprintf
!Куча советов в произвольном порядке:
string
это довольно длинное имя. Эффективно, так('').char
же, какstring.char
. Еще лучших результатов можно достичь, если использовать его вместе с точкой с запятой для переменных:,a=...; print(a:sub(1, 5))
но некоторыеstring
функции не принимают строки в качестве входных данных.tonumber
и+0
часто только тратить байты.load'your function code here'
вместоfunction()your function code here end
. Доступ к аргументам функции с помощью...
inside.a:gsub('.',load'my function')
кажется, самый короткий способ перебрать символы в строкеa:find('.',1,1)
(чтобы проверить эту проблему, попробуйте включить ее%
в разные места и проверить результаты). Бесчисленные идеи сломались из-за того, что Луа пытается проанализировать входные данные как шаблон.nil
это три байта,_
это один (это просто случайное имя, которое, скорее всего, не существует). Также любая цифра будет работать как истинное значение.x and i or o
. Это не просто троичный оператор - это полное логическое выражение. Фактически, это означает следующее: «еслиx
это правда, попробуйтеi
. Если x или i - ложь, верните o». Так что, еслиi
это неправда, результат естьo
. Кроме того, обаand
илиor
части могут быть опущены (x and i
,x or o
).math.floor
:5.3//1==5.0
. Обратите внимание, что полученное число всегда соответствует типу ввода (целое число / число с плавающей запятой).источник