답변:
이미 게시 된 것 외에도 시간이 지남에 따라 수집 한 몇 가지 트릭이 특정 순서없이 있습니다 ...
기호 ( "
문자열, {
테이블)로 구분 된 매개 변수가 하나만있는 함수 호출의 경우 매개 변수를 괄호로 묶을 필요는 없습니다.
예를 들어을 수행하는 대신 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 문자 변수로 지역화 하면 많은 바이트를 절약 할 수 있습니다.;). 이 트릭에 대한 Jim Bauwens의 공로.
루아 는 조건부 테스트에서 빈 문자열 (및 0
다른 언어와 달리)을 true 로 간주 하므로 예를 들어 대신 수행 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
무한 루프를 단축
무한 루프를 사용해야 할 때 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]
이 방법을 사용하면 비용이 가장 많이 드는 함수를 사용하여 하나의 입력을 취할 수 있습니다 (그러나 테이블을 입력으로 사용할 수 있습니다)
우리는 이제 골프를 즐기고 싶다면 명령 줄 인수를 사용하는 것이 길이라는 것을 알 수 있습니다.
arg[1]
...
(가) ...
루아에서 조금 특별하다, 그것의 압축을 푼 내용을 포함하는 변수 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 / elseif / if 문을 사용하는 데 3 원 미만의 비용이 드는 경우는 거의 없습니다. 그러한 진술의 상용구는 실제로 무겁습니다.
-- exemple with dumb values
if 1>0then v=1 else v=0 end
v=1>0 and 1or 0
간단한 예제를 사용하면 이미 12 바이트를 절약 할 수 있습니다. 다른 ifif를 수행해야하는 경우 점점 더 중요해 지므로주의하십시오!
또한 루아의 삼항은 특별 합니다. 작동 방식에는 몇 가지 조건이 있습니다. 관심있는 사람들을 위해 아래에서 설명하겠습니다.
루아의 제국은 형태입니다 <condition> and <case true: have to be a true value> or <case false: can be anything>
우선,의 진리표를 보자 or
. A or
는 함수로 간주 될 수 있습니다. 항상 값을 반환합니다. 다음은 반환되는 값입니다.
x | y ||x or y
------||-------
0 | 0 || y
0 | 1 || y
1 | 0 || x
1 | 1 || x
그것이 우리가 삼항을 구성 할 수있게 해주는 것입니다.
는 and
항상 반환, 우리가 조건을 평가할 수 것입니다 y
경우에 x and y
평가하여 true로.
그것의 문제는 우리가 원하는 경우 실패 할 것입니다 nil
또는 false
조건이 때 반환 할 false
. 예를 들어, 조건이 true 임에도 불구하고 다음은 항상 5를 반환합니다.
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))
이 단계를 더 진행할 수있는 경우가 있습니다. 루아과 같이, 문자열 조작에 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
를 사용하고 문자별로 문자를 반복 할 수 있습니다 . 때로는 필요에 따라 가장 잘 작동하지만 때로는 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 문 :
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
교체에 대한 귀하의 팁 있도록 평가하여 루아에서 false로, 다른 모든 것들은, 사실 x==0
, x==""
그리고 x==''
에 의해이 x
false입니다. 나는 현재 그것을 nil
:)로 바꾸고있다 .
이것들은 Lua 전용 (제 생각에는) 최적화입니다.
문자열은 산술 연산을 수행 할 때 자동으로 숫자로 변환됩니다. 조건문을주의해서 살펴보면 자동으로 변환되지 않습니다. 공간을 절약하면서 사용자 입력을 숫자로 취하는 데 좋습니다.
두 변수의 내용을 전환하는 데 임시 변수가 필요하지 않습니다. a,b=b,a
a와 b의 값을 바꿉니다.
또한, 위에서 말한 것을 확장하기 위해, 임의의 영숫자는 영숫자가 아닌 문자를 만질 수있다. 그래서 a,b=io.read():match"(.+)/(.+)"u,v=a,b
심지어 공백의 부족으로, 스크립트를 작업, 완벽한입니다.
대신에:
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 개의 문자 조합을 가진 테이블을 모두 사용할 수 있습니다.
루아에서 출력하는 두 가지 주요 방법이 있습니다
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
. ...
내부를 사용하여 함수 인수에 액세스하십시오 .a:gsub('.',load'my function')
문자열에서 문자를 반복하는 가장 짧은 방법 인 것 같습니다a:find('.',1,1)
문제를 테스트하기 위해 %
입력의 다양한 위치에 포함 시켜 결과를 확인해야합니다. 루아 (Lua)가 입력을 패턴으로 해석하려고 시도했기 때문에 수많은 아이디어가 깨졌습니다.nil
3 바이트, _
1입니다 (아마도 존재하지 않는 임의의 이름 일뿐입니다). 또한 모든 숫자는 진실한 가치로 작용합니다.x and i or o
. 그것은 단지 삼항 연산자가 아니라 완전한 논리적 표현입니다. 실제로는 다음을 의미합니다. " x
진실한 경우 시도하십시오 i
. x 또는 i가 거짓 인 경우 o를 반환하십시오." 따라서 i
진실이 아닌 경우 결과는 o
입니다. 또한 둘 다 and
또는 or
부분을 생략 할 수 있습니다 ( x and i
, x or o
).math.floor
: 대신에 1로 정수 나누기를 사용하십시오 5.3//1==5.0
. 결과 숫자는 항상 입력 유형 (정수 / 부동)의 유형을 따릅니다.