Tips untuk bermain golf di Lua

21

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.

scheurneus
sumber
6
Pertanyaan tip harus wiki komunitas. Tetapi bagi siapa pun yang menyerahkan ini sebagai "berdasarkan pendapat", Tips untuk Bermain Golf dalam Bahasa adalah pengecualian yang kami terima terhadap aturan itu. Sifat terbuka dari pertanyaan-pertanyaan ini adalah mengapa mereka bersifat komunitas.
Jonathan Van Matre

Jawaban:

9

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=1bisa 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 loadstringke variabel 1-char sebelumnya dan Anda akan menghemat banyak byte;). Penghargaan kepada Jim Bauwens untuk trik ini.

  • Lua menganggap string kosong (dan 0tidak seperti bahasa lain) sebagai true dalam tes bersyarat, jadi, misalnya, alih-alih melakukan while 1 do ... end, simpan 1 byte dengan menuliswhile''do ... end

Adriweb
sumber
(Menambahkan trik loadstring)
Adriweb
2
0 menjadi nilai yang benar-benar konyol
SuperJedi224
str+0Setara lainnya adalah ~~str, dapat bermanfaat untuk didahulukan
Felipe Nardi Batista
@FelipeNardiBatista namun itu hanya didukung pada Lua 5.3+
Adriweb
5

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.subdigunakan beberapa kali dalam program Anda, gunakan mis s=string.sub.

scheurneus
sumber
4
Ini juga berfungsi dalam banyak bahasa lain seperti Python dan Ruby.
nyuszika7h
4
Javascript dan Haskell dapat memiliki nilai fungsi juga.
haskeller bangga
Ini sama dengan s=("").subatau s=a.subuntuk variabel apa pun yang aberisi nilai string.
Egor Skriptunoff
Ini disebut fungsi kelas satu
Program Redwolf
5

Ini adalah bahasa yang sangat cocok untuk bermain golf ... tetapi beberapa tips umum yang muncul di benak Anda adalah:

  • Cobalah untuk menghindari persyaratan, karena if... then... else... endadalah pemborosan besar.
  • Sebagai gantinya, cobalah untuk fokus pada konstruksi bahasa yang lebih pendek, misalnya for i=1,5 do.
  • The #operator adalah cukup besar untuk bermain golf (dan secara umum).
Tal
sumber
5

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 ordapat 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 andyang memungkinkan kita untuk mengevaluasi kondisi, itu akan selalu kembali yjika x and ydievaluasi benar.

Masalahnya adalah itu akan gagal jika kita ingin nilatau falseakan 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
Katenkyo
sumber
Tolong, satu tip per jawaban.
ATaco
Perhatikan bahwa trik "Gunakan ruang sesedikit mungkin" hanya berfungsi pada Lua 5.2 dan yang lebih baru.
Adriweb
4

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 forloop dan string.subuntuk 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
Skyl3r
sumber
Kiat-kiat hebat, saya telah mengambil kebebasan untuk menyarankan edit ke posting Anda. Hanya nildan falsemenilai false di lua, semua yang lain benar, jadi tips Anda tentang mengganti x==0, x==""dan x==''oleh xitu salah. Saya sedang mengubahnya ke nil:).
Katenkyo
Ah, kamu benar. Terima kasih telah memperbaikinya!
Skyl3r
2

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,aakan 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,bjuga skrip yang berfungsi dengan baik, bahkan dengan kekurangan spasi.

Dwayne Slater
sumber
2

Gabungkan Tugas Variabel Lokal

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!

Deklarasikan Variabel Lokal melalui Parameter Fungsi yang Tidak Digunakan

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).

Phrogz
sumber
1
Diturunkan karena sama sekali tidak ada kasus di mana penggunaan localdibenarkan 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
Katenkyo
1

Fungsi Variadik

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 gsubdipicu.

Untuk menekan output kedua, enkapsulasi gsubparens Anda untuk memaksanya mengembalikan hanya satu nilai

print(String.gsub("aa",".","!"))    -- outputs "!!    2\n"
print((String.gsub("aa",".","!")))  -- outputs "!!\n"
Katenkyo
sumber
1

Tahu cara output

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.

Katenkyo
sumber
3
Itu printdan tidak printf!
val berkata Reinstate Monica
@val Wow, saya bahkan tidak tahu bagaimana saya bisa melakukan kesalahan itu. Terima kasih telah menunjukkannya, saya akan mengedit
Katenkyo
1

Banyak tips tanpa urutan tertentu:

  • stringadalah nama yang cukup panjang. Secara efisien, ('').charsama 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 stringfungsi tidak menggunakan string sebagai input.
  • Lua memiliki konversi otomatis antara string dan angka untuk sebagian besar kasus, jadi tonumberdan +0seringkali hanya menghabiskan byte.
  • Selalu gunakan load'your function code here'bukan function()your function code here end. Akses argumen fungsi menggunakan ...di dalam.
  • Beberapa fungsi string di Lua dapat digunakan dengan cara yang tidak diinginkan! Misalnya, a:gsub('.',load'my function')tampaknya merupakan cara terpendek untuk beralih pada karakter dalam string
  • Sementara mesin string sangat kuat, waspadalah terhadap kekuatannya saat menggunakan input pengguna sebagai pola! Karena itu, Anda mungkin harus menggunakan a: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.
  • niladalah tiga byte, _adalah satu (itu hanya nama acak yang kemungkinan besar tidak ada). Juga, angka apa pun akan berfungsi sebagai nilai kebenaran.
  • Ketahui logika Anda di belakang x and i or o. Ini bukan hanya operator ternary - ini adalah ekspresi logis yang lengkap. Bahkan, ini berarti yang berikut: "jika xitu benar, coba i. Jika salah x atau saya salah, kembalikan o". Jadi jika itidak benar, hasilnya adalah o. Juga, keduanya andatau orbagian dapat dihilangkan ( x and i, x or o).
  • Gunakan pembagian integer oleh salah bukan math.floor: 5.3//1==5.0. Harap dicatat bahwa angka yang dihasilkan selalu mengikuti jenis input satu (integer / float).
val mengatakan Reinstate Monica
sumber
1
"Juga, digit apa pun akan berfungsi sebagai nilai kebenaran." Hanya ingin menjelaskan bahwa ini termasuk 0, yang mungkin tidak terlalu intuitif untuk beberapa coders dari latar belakang C / C ++.
ouflak