Tips umum apa yang Anda miliki untuk bermain golf di Lua? Saya mencari ide yang dapat diterapkan pada masalah kode golf secara umum yang setidaknya agak spesifik untuk Lua (mis. "Hapus komentar" bukan jawaban). Silakan kirim satu tip per jawaban.
Tips umum apa yang Anda miliki untuk bermain golf di Lua? Saya mencari ide yang dapat diterapkan pada masalah kode golf secara umum yang setidaknya agak spesifik untuk Lua (mis. "Hapus komentar" bukan jawaban). Silakan kirim satu tip per jawaban.
Jawaban:
Selain yang sudah diposting, berikut adalah beberapa trik yang telah saya kumpulkan dari waktu ke waktu, tanpa urutan tertentu ...
Untuk panggilan fungsi yang hanya memiliki satu parameter yang dibatasi oleh simbol ( "
untuk string, {
untuk tabel), parameter tidak perlu dililitkan di dalam tanda kurung.
Misalnya, alih-alih melakukan print("hello")
, Anda cukup melakukan:print"hello"
Hapus spasi sebanyak mungkin - ini terutama mudah dilakukan setelah simbol yang menutup string (atau sebelum satu pembukaan), pemanggilan fungsi, tabel ...
Alih-alih print(42) a=1
bisa Anda lakukan print(42)a=1
. Contoh lain: print(a and-1 or-2)
.
Gunakan operator ternary saat Anda bisa! Alih-alih if a>0 then print("hello") else print("goodbye") end
, lebih suka print(a>0 and "hello" or "goodbye")
. Info lebih lanjut di sini .
(Ini benar-benar dapat menjadi lebih baik print(a>0 and"hello"or"goodbye")
:)
Gunakan gula sintaksis panggilan-kolon ketika Anda bisa: bukannya string.rep(str,12)
, lakukan str:rep(12)
. Itu juga berfungsi pada non-variabel dengan cara ini (dan hanya dengan cara ini):("a"):rep(5)
Alih-alih melakukan lakukan tonumber(str)
sajastr+0
Untuk fungsi tanpa parameter, alih-alih mendefinisikannya dengan cara biasa ( function tick() blabla() end
), Anda dapat melakukan ticks=loadstring"blabla()"
:, yang menyimpan 1 byte atau lebih, tergantung kontennya. Juga, jika Anda mendefinisikan beberapa fungsi, pelokalkan loadstring
ke variabel 1-char sebelumnya dan Anda akan menghemat banyak byte;). Penghargaan kepada Jim Bauwens untuk trik ini.
Lua menganggap string kosong (dan 0
tidak seperti bahasa lain) sebagai true dalam tes bersyarat, jadi, misalnya, alih-alih melakukan while 1 do ... end
, simpan 1 byte dengan menuliswhile''do ... end
str+0
Setara lainnya adalah ~~str
, dapat bermanfaat untuk didahulukan
Saya sudah memikirkan satu. Saya tidak tahu apakah itu berfungsi dalam beberapa bahasa lain, tetapi Lua adalah satu-satunya yang saya tahu yang memungkinkan Anda untuk menyimpan fungsi dalam variabel. Jadi, jika eg string.sub
digunakan beberapa kali dalam program Anda, gunakan mis s=string.sub
.
s=("").sub
atau s=a.sub
untuk variabel apa pun yang a
berisi nilai string.
Ini adalah bahasa yang sangat cocok untuk bermain golf ... tetapi beberapa tips umum yang muncul di benak Anda adalah:
if
... then
... else
... end
adalah pemborosan besar.for i=1,5 do
.#
operator adalah cukup besar untuk bermain golf (dan secara umum).Persingkat loop tak terbatas Anda
Ketika Anda harus menggunakan infinite loop, Anda mungkin berpikir untuk menggunakan while
, tetapi menggunakan label lebih pendek 2 byte:
while''do end
::a::goto a
Gunakan ruang sesedikit mungkin
Ada hal sederhana yang dapat Anda (ab) gunakan untuk menghapus lebih banyak ruang dari kode Anda. Spesifikasi Lua jelas tentang nama yang Anda berikan ke variabel: Mereka harus mulai dengan huruf. Ini menyiratkan bahwa, kadang-kadang, Anda dapat melewati spasi antara angka dan fungsi / variabel
x=0>1 and 0or 1print(x)
Kemungkinan untuk menghapus ruang tergantung pada huruf berikut nomornya, inilah surat yang tidak akan memungkinkan Anda untuk melakukan ini:
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)
Dengan menggunakan ini, dan memperhatikan bagaimana Anda memanggil variabel Anda, Anda dapat membuat sebagian besar kode sumber Anda bebas-ruang.
Ambil contoh sudah ada di sini, dan menggunakan saran ini, berikut ini satu byte lagi yang bisa Anda hilangkan :).
print(a and-1 or-2)
print(a and-1or-2)
Gunakan metode input yang benar
Jika kita melihat pelat dan biaya untuk setiap jenis input utama , inilah yang kami miliki:
function f(x)x end
io.read()
arg[1]
Masing-masing dari metode ini memungkinkan kita untuk mengambil 1 input, dengan fungsi menjadi satu dengan biaya terberat (tetapi memungkinkan kita mengambil tabel sebagai input)
Kita sekarang dapat melihat bahwa menggunakan argumen baris perintah adalah cara yang harus dilakukan jika Anda ingin bermain golf, tetapi perlu diingat: ini bisa menjadi lebih singkat
arg[1]
...
Itu ...
agak istimewa di lua, itu adalah variabel yang berisi konten yang tidak dibongkar arg
, atau parameter yang dibongkar jika ada fungsi variadic.
Saat Anda harus mendapatkan lebih dari satu input, dan menggunakan masing-masing input, sebaiknya simpan dalam variabel. Berikut adalah beberapa cara untuk menyimpan 2 input dalam variabel
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
dan di sini adalah panggilan terpendek yang dapat Anda lakukan tanpa variabel:
... -- 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
Dari titik di mana Anda memiliki 3 argumen, atau ketika Anda menggunakan 2 argumen, dengan satu argumen digunakan dua kali, Anda sudah mendapatkan byte karena a,b=...
! :)
Hampir tidak pernah digunakan jika!
Hampir tidak ada kasus di mana menggunakan pernyataan if / elseif / if akan menelan biaya kurang dari satu ternary. pelat untuk pernyataan seperti itu benar-benar berat:
-- exemple with dumb values
if 1>0then v=1 else v=0 end
v=1>0 and 1or 0
Dengan contoh sederhana, Anda sudah menyimpan 12 byte, ketika Anda harus melakukan beberapa hal lain, itu menjadi semakin penting, jadi waspadalah!
Juga, terner di lua adalah spesial , ada beberapa kondisi dalam cara kerjanya, bagi yang berminat, saya akan jelaskan di bawah ini:
Ternary di lua adalah bentuk <condition> and <case true: have to be a true value> or <case false: can be anything>
Pertama - tama, mari kita lihat tabel kebenaran or
. A or
dapat dianggap sebagai fungsi: selalu mengembalikan nilai, inilah nilai yang dikembalikan:
x | y ||x or y
------||-------
0 | 0 || y
0 | 1 || y
1 | 0 || x
1 | 1 || x
Itulah yang memungkinkan kita untuk membangun ternary kita.
Inilah and
yang memungkinkan kita untuk mengevaluasi kondisi, itu akan selalu kembali y
jika x and y
dievaluasi benar.
Masalahnya adalah itu akan gagal jika kita ingin nil
atau false
akan kembali ketika kondisinya false
. Misalnya, yang berikut ini akan selalu mengembalikan 5, meskipun kondisinya benar.
v = true and false or 5
Berikut ini adalah langkah demi langkah evaluasi terner untuk menjelaskan cara kerjanya (ini akan berguna ketika Anda harus membuat sarang mereka :))
-- 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
Saya telah menyusun beberapa tips juga. Saya yakin sebagian dari saya akan tumpang tindih dengan yang sudah dinyatakan, tapi bagaimanapun saya akan memasukkan mereka dalam uraian menciptakan jawaban yang lebih lengkap.
Tetapkan fungsi berulang untuk variabel
Lua memungkinkan Anda untuk menetapkan fungsi ke variabel. Bahkan satu karakter variabel. Ini berarti jika Anda mengulangi fungsi string.sub(x, y)
lebih dari dua kali, Anda akan mendapat manfaat dari menugaskannya ke variabel.
Tanpa menetapkan ke variabel (69 karakter):
print(string.sub(x, y))
print(string.sub(x, y))
print(string.sub(x, y))
Menetapkan ke variabel (51 karakter):
s=string.sub
print(s(x,y))
print(s(x,y))
print(s(x,y))
Ada kasus di mana Anda dapat mengambil ini selangkah lebih maju. Lua memungkinkan OOP untuk memanipulasi string, seperti: str:sub(x, y)
atau str.sub(x, y)
Ini membuka opsi baru untuk kode kita. Anda dapat menetapkan variabel ke fungsi dengan referensi itu seperti yang ditunjukkan (46 karakter.)
s=z.sub
print(s(x, y))
print(s(x, y))
print(s(x, y))
Gunakan cara paling efisien untuk mengurai string
Anda mungkin menemukan diri Anda menggunakan for
loop dan string.sub
untuk mengulangi karakter demi karakter di Lua. Terkadang ini bekerja dengan baik, tergantung pada kebutuhan Anda, tetapi di lain waktu, string.gmatch akan bekerja dalam karakter yang lebih sedikit. Berikut ini contoh keduanya:
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
Dan saat bermain golf, perbedaannya lebih menonjol:
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
Menata Ulang Tugas Untuk Mengoptimalkan Ruang Putih
Di Lua, Anda tidak harus meletakkan karakter spasi antara tanda kurung tertutup atau tanda kutip akhir dan karakter berikutnya. Sejauh ini, saya telah menemukan dua kasus di mana restrukturisasi dengan pemikiran ini akan memotong karakter.
Menetapkan variabel:
x,y=io.read(),0 print(x)
vs.
y,x=0,io.read()print(x)
Jika Pernyataan:
if x:sub(1,1)==1 then
vs
if 1==x:sub(1,1)then
Kembalikan karakter sesedikit mungkin
Jika Anda harus mengembalikan nilai benar atau salah, maka tampaknya Anda harus menggunakan setidaknya 5 karakter untuk nilai pengembalian. Pada kenyataannya, berikut ini juga berfungsi:
return true
return false
vs
return 1>0
return 0>1
nil
dan false
menilai false di lua, semua yang lain benar, jadi tips Anda tentang mengganti x==0
, x==""
dan x==''
oleh x
itu salah. Saya sedang mengubahnya ke nil
:).
Ini hanya optimasi Lua (saya pikir):
String secara otomatis dikonversi menjadi angka ketika melakukan operasi aritmatika. Hanya hati-hati untuk pernyataan bersyarat, mereka tidak secara otomatis mengkonversi. Ini bagus untuk mengambil input pengguna sebagai angka sambil menghemat ruang.
Mengalihkan konten dari dua variabel tidak memerlukan variabel sementara. a,b=b,a
akan menukar nilai a dan b.
Juga, untuk memperluas apa yang dikatakan di atas, karakter alfanumerik apa pun dapat menyentuh karakter non alfanumerik. Begitu a,b=io.read():match"(.+)/(.+)"u,v=a,b
juga skrip yang berfungsi dengan baik, bahkan dengan kekurangan spasi.
Dari pada:
local a=42
local b=17
local c=99
Gunakan penugasan paralel:
local a,b,c=42,17,19
6 byte disimpan untuk setiap variabel!
Dari pada:
function foo(a,b) local c,d ... end
function bar(a,b) local c,d=42,17 ... end
Menggunakan
function foo(a,b,c,d) ... end
function bar(a,b,c,d) c,d=42,17 ... end
6 byte disimpan (minus 1-2 byte untuk setiap variabel yang mungkin diduplikasi).
local
dibenarkan ketika bermain golf, karena Anda hanya perlu menggunakan nama yang berbeda. Kita bisa menggunakan SEMUA nama hingga 7 charachters DAN tabel dengan indeks string hingga 7 kombinasi charachters sebelum kita memukul sesuatu yang bisa mendapat manfaat dari menggunakan penduduk setempat
Fungsi variadic utama yang akan merepotkan Anda adalah print()
. Misalnya, ketika Anda menggunakannya sepanjang String.gsub()
itu akan mencetak string yang Anda modifikasi DAN berapa kali gsub
dipicu.
Untuk menekan output kedua, enkapsulasi gsub
parens Anda untuk memaksanya mengembalikan hanya satu nilai
print(String.gsub("aa",".","!")) -- outputs "!! 2\n"
print((String.gsub("aa",".","!"))) -- outputs "!!\n"
Ada dua metode utama keluaran dalam lua
io.write() -- outputs without trailing newline
print() -- outputs with trailing new line and shorter by 3 bytes
Ketika Anda harus menggabungkan beberapa kali, Anda dapat mempersingkatnya dengan menggunakan io.write()
variabel satu huruf alih-alih operator gabungan standar...
i(a) -- i was defined as io.write
s=s..a
Anda mendapatkan 2 byte pada setiap panggilan sambil membayar dimuka
i=io.write -- longer by 6 bytes
s=""
Anda bahkan berada pada rangkaian ketiga, dan mulai mendapatkan byte pada keempat.
print
dan tidak printf
!
Banyak tips tanpa urutan tertentu:
string
adalah nama yang cukup panjang. Secara efisien, ('').char
sama dengan string.char
. Bahkan hasil yang lebih baik dapat dicapai jika Anda menggunakannya bersama-sama dengan tanda titik koma pada variabel:, a=...; print(a:sub(1, 5))
tetapi beberapa string
fungsi tidak menggunakan string sebagai input.tonumber
dan +0
seringkali hanya menghabiskan byte.load'your function code here'
bukan function()your function code here end
. Akses argumen fungsi menggunakan ...
di dalam.a:gsub('.',load'my function')
tampaknya merupakan cara terpendek untuk beralih pada karakter dalam stringa:find('.',1,1)
(untuk menguji masalah ini, coba sertakan %
di berbagai tempat di masukan Anda dan lihat hasilnya). Banyak ide yang pecah karena Lua mencoba mengurai input sebagai pola.nil
adalah tiga byte, _
adalah satu (itu hanya nama acak yang kemungkinan besar tidak ada). Juga, angka apa pun akan berfungsi sebagai nilai kebenaran.x and i or o
. Ini bukan hanya operator ternary - ini adalah ekspresi logis yang lengkap. Bahkan, ini berarti yang berikut: "jika x
itu benar, coba i
. Jika salah x atau saya salah, kembalikan o". Jadi jika i
tidak benar, hasilnya adalah o
. Juga, keduanya and
atau or
bagian dapat dihilangkan ( x and i
, x or o
).math.floor
: 5.3//1==5.0
. Harap dicatat bahwa angka yang dihasilkan selalu mengikuti jenis input satu (integer / float).