您在Lua打高尔夫球有哪些一般秘诀?我正在寻找可以应用于编码高尔夫问题的想法,这些想法至少在某种程度上是特定于Lua的(例如,“删除评论”不是答案)。请为每个答案发布一个提示。
您在Lua打高尔夫球有哪些一般秘诀?我正在寻找可以应用于编码高尔夫问题的想法,这些想法至少在某种程度上是特定于Lua的(例如,“删除评论”不是答案)。请为每个答案发布一个提示。
Answers:
除了已经发布的那些,这里还有一些我逐渐收集的技巧,没有特定的顺序...
对于仅由一个符号分隔的一个参数的函数调用("
对于字符串,{
对于表),该参数不需要用括号括起来。
例如,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)
do str:rep(12)
。这样也可以(仅通过这种方式)对非变量起作用:("a"):rep(5)
而不是做的tonumber(str)
只是做str+0
对于没有参数的函数function tick() blabla() end
,您可以执行:,而不是使用常规方法()定义它们ticks=loadstring"blabla()"
,根据内容,它可以节省1个或更多字节。另外,如果定义了多个函数,请loadstring
在之前将其本地化为1个字符的变量,这样可以节省很多字节;)。感谢这个技巧的吉姆·鲍文斯(Jim Bauwens)。
Lua 在条件测试0
中将空字符串(与其他语言不同)认为是真实的,因此,例如,与其这样做while 1 do ... end
,不如通过写入来节省1个字节while''do ... end
str+0
等效项是~~str
,可以优先使用它
我已经想到了一个。我不知道它是否可以在其他语言中工作,但是Lua是我所知道的唯一允许您将函数存储在变量中的语言。因此,如果string.sub
在程序中多次使用了eg,请使用eg s=string.sub
。
s=("").sub
或包含字符串值的s=a.sub
任何变量a
。
缩短无限循环
当您必须使用无限循环时,您可能会想到使用while
,但是使用标签要短2个字节:
while''do end
::a::goto a
使用尽可能少的空间
您可以使用简单的方法从代码中删除更多的空间。Lua的规范很清楚您为变量指定的名称:它们必须以字母开头。这意味着有时您可以跳过数字与函数/变量之间的空格
x=0>1 and 0or 1print(x)
删除空格的可能性取决于数字后面的字母,这是不允许您执行此操作的字母:
a,b,c,d,e,f -- They would be interpreted as hexadecimal
x -- only fail when after a 0, other number are fine
-- (0x indicates the following is an hexadecimal number)
通过使用它,并注意如何调用变量,您可以使大部分源代码都没有空间。
在这里已经拿起一个示例,并使用此建议,这里还有一个字节可以删除:)。
print(a and-1 or-2)
print(a and-1or-2)
使用正确的输入法
如果我们查看每种主要输入类型的样板和成本,那么我们就会得到:
function f(x)x end
io.read()
arg[1]
这种方法的每一种都允许我们接受1个输入,而函数是成本最高的函数(但允许我们接受一张表作为输入)
现在我们可以看到,如果您想打高尔夫球,使用命令行参数是必经之路,但请注意:它甚至可以更短
arg[1]
...
的...
是在LUA有点特殊,它含有的解压缩内容的变量arg
,或者在一个可变参数函数的情况下,解压后的参数。
当您将不得不获得多个输入并使用每个输入时,最好将它们保存在变量中。这是将2个输入保存到变量中的一些方法
a=arg[1]b=arg[2] -- highly un-efficient, costs 8 bytes by variable
a,b=unpack(arg) -- costs 15, but at least doesn't depends on the number of argument
a,b=... -- only costs 7
这是没有变量就可以完成的最短调用:
... -- using a allow a gain of 1-2 bytes at each use
arg[2] -- using b allow a gain of 4-5 bytes at each use
从具有3个参数的点开始,或者当您使用2个参数(其中一个使用了两次)时,由于a,b=...
!,您已经在获取字节。:)
几乎从不使用if!
在几乎没有情况下,使用if / elseif / if语句的成本将低于三元组。这样的声明的样板真的很沉重:
-- exemple with dumb values
if 1>0then v=1 else v=0 end
v=1>0 and 1or 0
通过一个简单的示例,您已经节省了12个字节,当您不得不做其他操作时,它变得越来越重要,因此请注意这一点!
另外,lua中的三元是特殊的,它们的工作方式有一定条件,对于那些感兴趣的人,我将在下面进行解释:
lua中的三元形式为 <condition> and <case true: have to be a true value> or <case false: can be anything>
首先,让我们看一下的真值表or
。or
可以将A 视为函数:它总是返回一个值,这是它返回的值:
x | y ||x or y
------||-------
0 | 0 || y
0 | 1 || y
1 | 0 || x
1 | 1 || x
这就是允许我们构造三元组的原因。
该and
是什么让我们评估条件,它总是返回y
如果x and y
计算结果为True。
问题是如果条件为,如果我们希望a nil
或false
返回,它将失败false
。例如,以下条件将始终返回5,即使条件为true。
v = true and false or 5
这是对三元数的逐步评估,以说明其工作原理(这对于必须嵌套它们的情况很有用:)
-- let's use our dumb ternary
= true and false or 5
-- and statement will be evaluated first, leading to
= false or 5
-- and we saw how the or works
= 5
我也整理了一些技巧。我敢肯定,我的一些人会与已经陈述的人重叠,但是无论如何,我都会将它们包括在内,以期创建一个更完整的答案。
将重复的函数分配给变量
Lua允许您将函数分配给变量。甚至一个字符变量。这意味着,如果重复执行该函数string.sub(x, y)
两次以上,则可以将其分配给变量,从而受益匪浅。
不分配变量(69个字符):
print(string.sub(x, y))
print(string.sub(x, y))
print(string.sub(x, y))
分配给一个变量(51个字符):
s=string.sub
print(s(x,y))
print(s(x,y))
print(s(x,y))
在某些情况下,您可以更进一步。Lua允许OOP进行字符串操作,如下所示:str:sub(x, y)
或str.sub(x, y)
这为我们的代码打开了新的选项。您可以通过如下所示的引用将变量分配给该函数(46个字符)。
s=z.sub
print(s(x, y))
print(s(x, y))
print(s(x, y))
使用最有效的方式解析字符串
您可能会发现自己使用for
循环并string.sub
在Lua中逐个字符地进行迭代。有时,这可能效果最好,具体取决于您的需求,但是有时,string.gmatch将以更少的字符工作。这是两个示例:
s=io.read()
for a = 1, s:len() do
print(s:sub(a, a))
end
for i in io.read():gmatch('.') do
print(i)
end
当打高尔夫球时,区别更加明显:
s=io.read()for a=1,s:len()do print(s:sub(a, a))end
for i in io.read():gmatch'.'do print(i)end
重组分配以优化空白
在Lua中,不必在圆括号或引号和下一个字符之间放置空格。到目前为止,我发现了两种情况,考虑到这种重组会削减字符。
分配变量:
x,y=io.read(),0 print(x)
vs.
y,x=0,io.read()print(x)
如果声明:
if x:sub(1,1)==1 then
vs
if 1==x:sub(1,1)then
返回尽可能少的字符
如果必须返回一个true或false值,则看来必须至少使用5个字符作为返回值。实际上,以下内容同样适用:
return true
return false
vs
return 1>0
return 0>1
nil
和false
计算结果为在Lua假的,其他的一切都是真的,所以你对更换的提示x==0
,x==""
并x==''
通过x
是假的。我当前将其更改为nil
:)。
代替:
local a=42
local b=17
local c=99
使用并行分配:
local a,b,c=42,17,19
每个变量保存6个字节!
代替:
function foo(a,b) local c,d ... end
function bar(a,b) local c,d=42,17 ... end
使用
function foo(a,b,c,d) ... end
function bar(a,b,c,d) c,d=42,17 ... end
保存6个字节(每个可能重复的变量减去1-2个字节)。
local
是因为在打高尔夫球时绝对没有理由合理使用,因为您只需要使用其他名称即可。我们可能会使用所有名称最多7个字符和具有最多7个字符组合的字符串索引的表,然后才能找到可以从使用本地人中受益的东西
在lua中有两种主要的输出方法
io.write() -- outputs without trailing newline
print() -- outputs with trailing new line and shorter by 3 bytes
当您必须串联多个时,可以通过使用io.write()
分配给一个字母变量而不是标准串联运算符来缩短该时间..
i(a) -- i was defined as io.write
s=s..a
您每次通话时获得2个字节,同时支付一些预付款
i=io.write -- longer by 6 bytes
s=""
您甚至在第三个连接上,并在第四个连接上开始获取字节。
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)
(要测试此问题,请尝试%
在输入中的各个位置添加并检查结果)。由于Lua尝试将输入解析为模式,因此无数创意破灭。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
。请注意,结果数字始终遵循输入一的类型(整数/浮点数)。