回答:
既に投稿されたものに加えて、ここに私が時間の経過とともに集めたいくつかのトリックを、順不同で...
シンボルで区切られた1つのパラメーターのみを持つ関数呼び出し("
ストリング{
用、テーブル用)の場合、パラメーターを括弧で囲む必要はありません。
たとえば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の功績によるものです。
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
できるだけ少ないスペースを使用してください
コードからさらに多くのスペースを削除するために(ab)使用できる簡単なことがあります。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)
これを使用し、変数の呼び出し方に注意を払うことにより、ソースコードのほとんどをスペースフリーにすることができます。
すでにここで例を取り上げ、このアドバイスを使用して、もう1つバイトを削除できます:)。
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つの引数を使用し、1つの引数を2回使用する場合、a,b=...
!:)
ifを使用することはほとんどありません!
if / elseif / ifステートメントの使用が3項よりも少ない場合はほとんどありません。そのような声明の定型文は本当に重いです:
-- exemple with dumb values
if 1>0then v=1 else v=0 end
v=1>0 and 1or 0
簡単な例では、すでに12バイトを保存していますが、elseifを実行する必要がある場合は、より重要になりますので、注意してください!
また、luaの3項は特別なものであり、それらがどのように機能するかについていくつかの条件があります。興味がある人のために、以下で説明します。
luaの三項は <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では、関数を変数に割り当てることができます。1文字の変数でも。つまり、関数をstring.sub(x, y)
2回以上繰り返すと、変数に割り当てることでメリットが得られます。
変数に割り当てない場合(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))
最も効率的な方法で文字列を解析します
Luaで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では、閉じ括弧または終了引用符と次の文字の間にスペース文字を入れる必要はありません。これまでのところ、私はこれを念頭に置いて再構築するとキャラクターがカットされる2つのケースを見つけました。
変数の割り当て:
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
交換についてあなたのヒントので、LUAでfalseと評価され、他のすべては、真であるx==0
、x==""
とx==''
によってはx
falseです。現在nil
:)に変更しています。
これらはLuaのみ(と思う)の最適化です。
文字列は、算術演算を行うときに自動的に数値に変換されます。条件文に注意してください、それらは自動的に変換しません。これは、スペースを節約しながらユーザー入力を数値として取り込むのに最適です。
2つの変数の内容を切り替えるには、一時変数は必要ありません。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
あなたが別の名前を使用する必要があるため、ゴルフをするときに使用が正当化される場合は絶対にないため、ダウン投票されました。地元の人々を
luaで出力する主な方法は2つあります
io.write() -- outputs without trailing newline
print() -- outputs with trailing new line and shorter by 3 bytes
複数回連結する必要がある場合io.write()
は、標準の連結演算子の代わりに1文字の変数に割り当てられたものを使用することで短縮できます。..
i(a) -- i was defined as io.write
s=s..a
前払いで通話ごとに2バイト獲得
i=io.write -- longer by 6 bytes
s=""
3番目の連結でさえ、4番目にバイトを獲得し始めます。
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
3バイト、_
1 バイトです(ランダムな名前であり、ほとんど存在しません)。また、どの数字も真理値として機能します。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
。結果の数値は常に入力タイプ(整数/浮動小数点数)の後に続くことに注意してください。