Tips umum apa yang Anda miliki untuk bermain golf di Julia? Saya mencari ide yang dapat diterapkan pada masalah kode golf secara umum yang setidaknya agak spesifik untuk Julia (mis. "Hapus komentar" bukan jawaban).
20
CATATAN: Di bawah ini mungkin berisi beberapa tips yang sudah ketinggalan zaman, karena Julia belum cukup stabil dalam hal struktur, belum.
Beberapa trik untuk menyimpan beberapa karakter
\ =div
, dan Anda kemudian dapat mengetik a\b
bukan div(a,b)
. Perhatikan ruang - ini diperlukan untuk menghindari penguraian sebagai operator "\ =". Juga perhatikan bahwa, jika kelebihan beban pada level REPL prompt, gunakan (\)=Base.(\)
atau \ =Base. \
untuk meresetnya. CATATAN: beberapa fungsi memiliki operator UTF-8 yang sudah ditentukan sebelumnya, seperti ÷
untuk div
, seperti yang dicatat oleh Alex A.a>0?"Hi":""
, gunakan "Hi"^(a>0)
untuk menyimpan satu byte, atau untuk boolean a, gunakan "Hi"^a
untuk menyimpan tiga byte.a=split("Hi there"," ")
, Anda mungkin dapat menghindari a[1]
dan a[2]
menggunakan a,b=split("Hi there"," ")
, yang dapat dirujuk sebagai a
dan b
, menghemat tiga byte untuk setiap penggunaan, dengan biaya hanya dua karakter tambahan saat penugasan. Jelas, jangan lakukan ini jika Anda dapat bekerja dengan operasi vektor.[]
- untuk array, ekspresi A[]
sama dengan A[1]
. Perhatikan bahwa ini tidak berfungsi untuk Strings jika Anda ingin mendapatkan karakter pertama, atau untuk Tuples.==[]
untuk array dan ==()
untuk tuple; sama halnya, untuk yang negatif, gunakan !=[]
dan !=()
. Untuk string, gunakan ==""
untuk kosong, tetapi gunakan >""
untuk tidak-kosong, karena "" secara leksikografis sebelum string lain.x<=1&&"Hi"
dapat ditulis sebagai x>1||"Hi"
, menyimpan karakter (selama kembalinya boolean tidak penting).in('^',s)
daripada contains(s,"^")
. Jika Anda dapat menggunakan karakter lain, Anda dapat menyimpan sedikit lebih banyak dengan '^'∈s
, tetapi perhatikan bahwa ∈
3 byte di UTF-8.minimum(x)
atau maximum(x)
, menggunakan min(x...)
atau max(x...)
, untuk mencukur satu karakter dari kode Anda, jika Anda tahu x
akan memiliki setidaknya dua elemen. Atau, jika Anda tahu semua elemen x
akan non-negatif, gunakan minabs(x)
ataumaxabs(x)
r"(?m)match^ this"
, mengetik r"match^ this"m
, menyimpan tiga karakter.reverse(x)
lebih panjang satu byte daripada flipud(x)
dan akan melakukan operasi yang sama, sehingga yang terakhir lebih baik.{[1,2]}
, tidak {1,2}
) - untuk Julia 0.4, Anda perlu Any[[1,2]]
.end
dalam pengindeksan array, secara otomatis akan dikonversi ke panjang array / string. Jadi alih-alih k=length(A)
, gunakan A[k=end]
untuk menyimpan 3 karakter. Perhatikan bahwa ini mungkin tidak bermanfaat jika Anda ingin segera menggunakan k. Ini juga berfungsi dalam kasus multidimensi - A[k=end,l=end]
akan mendapatkan ukuran setiap dimensi A
- namun, (k,l)=size(A)
lebih pendek satu byte dalam kasus ini, jadi gunakan hanya jika Anda ingin segera mengakses elemen terakhir pada saat yang sama.A[k=1:end]
, dalam hal ini k
akan memegang pencocokan iterator 1:length(A)
. Ini bisa berguna ketika Anda ingin juga menggunakan array A
pada saat yang bersamaan.collect(A)
, gunakan [A...]
, yang akan melakukan hal yang sama dan menyimpan 4 byte."$(s[i])"
atau dec(s[i])
untuk ekspresi atau variabel multi-karakter, dan "$i"
untuk variabel-karakter tunggal.?:
alih-alih &&
atau ||
untuk penugasan bersyarat - yaitu, jika Anda ingin melakukan penugasan hanya pada kondisi tertentu, Anda dapat menyimpan satu byte dengan menulis cond?A=B:1
daripada cond&&(A=B)
, atau cond?1:A=B
bukannya cond||(A=B)
. Perhatikan bahwa 1
, di sini, adalah nilai dummy.union
atau ∪
bukannyaunique
- union(s)
akan melakukan hal yang sama seperti unique(s)
, dan menyimpan byte dalam proses. Jika Anda dapat menggunakan karakter non-ASCII, maka ∪(s)
akan melakukan hal yang sama, dan ∪
hanya biaya 3 byte, bukan 5 byte union
.
split("Hi there")
karena argumen pola default ke spasi.Definisikan ulang operator untuk menetapkan fungsi
Mendefinisikan ulang operator dapat menyimpan banyak byte dalam tanda kurung dan koma.
Operator unary rekursif
Sebagai contoh unary, bandingkan implementasi rekursif dari urutan Fibonacci berikut:
Cobalah online!
Operator yang didefinisikan ulang mempertahankan prioritas awal.
Perhatikan bahwa kita tidak bisa sekadar bertukar
!
demi~
, karena~
sudah ditentukan untuk bilangan bulat, sementara!
hanya ditentukan untuk Boolean.Operator biner
Bahkan tanpa rekursi, mendefinisikan ulang operator lebih pendek daripada mendefinisikan fungsi biner. Bandingkan definisi tes keterpisahan sederhana berikut.
Cobalah online!
Operator biner rekursif
Berikut ini menggambarkan cara mendefinisikan ulang operator biner untuk menghitung fungsi Ackermann:
Cobalah online!
Perhatikan bahwa
^
ini lebih lama daripada menggunakan pengenal biasa, karena prioritasnya terlalu tinggi.Seperti disebutkan sebelumnya
tidak akan berfungsi untuk argumen integer, karena
|
sudah ditentukan dalam kasus ini. Definisi untuk bilangan bulat dapat diubah dengantapi itu terlalu lama. Namun, tidak bekerja jika kita melewati pelampung sebagai argumen kiri dan integer sebagai argumen yang tepat.
sumber
Jangan terlalu mudah tergoda oleh faktor (n) Fungsi pustaka basis yang menggoda
factor(n)
memiliki kelemahan fatal: ia mengembalikan faktorisasi bilangan bulat Anda dalamDict
tipe yang tidak berurutan . Dengan demikian, itu memerlukan biayacollect(keys())
dancollect(values())
dan berpotensi juga acat
dan asort
untuk mendapatkan data yang Anda inginkan. Dalam banyak kasus, mungkin lebih murah untuk hanya faktor dengan pembagian percobaan. Sedih, tapi benar.Gunakan peta
map
adalah alternatif yang bagus untuk perulangan. Waspadai perbedaan antaramap
danmap!
dan manfaatkan fungsionalitas in-place yang terakhir ketika Anda bisa.Gunakan mapreduce
mapreduce
memperluas fungsionalitas peta lebih jauh dan bisa menjadi byte-saver yang signifikan.Fungsi anonim sangat bagus! ..terutama ketika diteruskan ke
map
fungsi yang disebutkan di atas .Fungsi array kumulatif
cumprod
,cumsum
, yang beraromacummin
dan fungsi lainnya bernama sama memungkinkan operasi kumulatif sepanjang dimensi tertentu dari sebuah array n-dimensi. (Atau * tidak * ditentukan jika arraynya 1-d)Notasi singkat untuk Apa saja Ketika Anda ingin memilih semua dimensi tertentu dari array multi-dimensi (atau Diktik), misalnya
A[Any,2]
, Anda dapat menyimpan byte dengan menggunakanA[:,2]
Gunakan notasi satu-baris untuk fungsi, alih-alih
function f(x) begin ... end
Anda sering dapat menyederhanakannyaf(x)=(...)
Gunakan operator ternary. Ini bisa menjadi penghemat ruang untuk konstruksi ekspresi If-Then-Else ekspresi tunggal. Peringatan: Meskipun mungkin dalam beberapa bahasa lain, Anda tidak dapat menghilangkan bagian setelah titik dua di Julia. Selain itu, operator adalah level ekspresi dalam Julia, jadi Anda tidak dapat menggunakannya untuk eksekusi kode blok secara keseluruhan.
if x<10 then true else false end
vs.x<10?true:false
sumber
Iterate alih fungsi
Ini juga dimungkinkan dalam bahasa lain, tetapi biasanya lebih lama dari metode yang sederhana. Namun, kemampuan Julia untuk mendefinisikan kembali operator unary dan biner membuatnya cukup golf.
Misalnya, untuk menghasilkan tabel penambahan, pengurangan, perkalian, dan pembagian untuk bilangan asli dari 1 hingga 10, orang dapat menggunakan
yang telah mengubah biner Operator
|
sebagai+
,-
,*
dan÷
, kemudian menghitungx|y
untuk setiap operasi danx
dany
dalam rentang yang diinginkan.Ini juga berfungsi untuk operator unary. Misalnya, untuk menghitung bilangan kompleks 1 + 2i , 3-4i , -5 + 6i dan -7-8i , negatifnya, konjugat kompleksnya dan inversi multiplikatifnya, orang dapat menggunakan
yang telah mengubah unary operator yang
~
sebagai+
,-
,conj
daninv
, kemudian menghitung~x
untuk semua bilangan kompleks yang diinginkan.Contoh dalam kontes yang sebenarnya
Urutan Perempuan dan Laki-laki (biner)
Permutasi Kasus (unary)
sumber
Kata kunci terkadang dapat langsung mengikuti konstanta tanpa perlu spasi atau titik koma. Sebagai contoh:
Perhatikan kurangnya ruang antara
1
danend
. Ini juga berlaku untukend
terjadi setelah paren dekat, yaitu)end
.Lakukan pembagian integer menggunakan
÷
alih - alihdiv()
atau kelebihan operator. Perhatikan bahwa÷
bernilai 2 byte dalam UTF-8.Gunakan
vec()
atauA[:]
(untuk beberapa larikA
) daripadareshape()
bila memungkinkan.Buat fungsi daripada program lengkap bila diizinkan dalam aturan tantangan. Lebih pendek untuk mendefinisikan fungsi yang menerima input daripada mendefinisikan variabel dengan membaca dari stdin. Sebagai contoh:
Variabel dapat ditambahkan di dalam argumen ke fungsi. Misalnya, berikut ini adalah jawaban saya untuk tantangan Find the Binary Number 1-Sparse Next :
Ini lebih pendek daripada menambah
n
bagian dalam loop.sumber
return
f(x)=x+4
identik tetapi lebih pendek darif(x)=return x+4
. Julia selalu mengembalikan hasil dari pernyataan terakhir.[x for x in 1:4]
lebih dari 3 karakter, tetapi setara dengan[x for x=1:4]
sumber
Gunakan panggilan fungsi Siaran.
Diperkenalkan di Julia 0.5. Itu seperti peta, tetapi menggunakan lebih sedikit karakter, dan tidak menyiarkan perilaku di atas itu args - yang berarti Anda dapat menulis lebih sedikit lambda untuk menangani hal-hal.
Daripada:
map(f,x)
- 8 karakter.f.(x)
- 5 karakterLebih baik lagi:
map(a->g(a,y),x)
- 16 karakterg.(x,[y])
- 9 karaktersumber