Masalahnya adalah bahwa banyak bahasa adalah (seringkali berumur pendek) yang eksperimental dengan paradigma yang sangat tidak khas, yang mana ekspresi pemrograman tipikal tidak masuk akal sama sekali. Jadi "mayoritas dari semua bahasa" hampir tidak mungkin untuk dipenuhi. Anda harus membatasi dengan beberapa cara, misalnya untuk "mayoritas bahasa yang digunakan secara teratur pada codegolf.SE". Saat ini, jawabannya agak mirip "mayoritas bahasa yang diturunkan dari bahasa C", tetapi mereka, meskipun sebagian besar dari semua kode tertulis ditulis di dalamnya, bukan mayoritas bahasa .
Berhenti menghidupkan counterclockwis
3
kiri sekitar, saya kira kita semua tahu apa maksudnya secara kasar. Ini sebagian besar tentang optimasi bahasa-independen, yaitu yang tidak hanya berguna di Brainfuck tetapi mungkin juga Python, C, Java dan Fortran sekaligus. Gagasan umum yang dapat Anda terapkan dalam banyak bahasa yang berfungsi serupa. Saya tidak berpikir ada kebutuhan untuk menjadi tepat dan spesifik dalam tips dan pertanyaan CW. Ini tentang membantu orang lain bermain golf, bukan membuat mereka kesal.
Joey
14
Semoga tidak ada yang menciptakan bahasa yang disebut <all languages>...
mbomb007
Jawaban:
72
Gabungkan Loop
Anda biasanya dapat menggabungkan dua loop konsekuen, atau dua loop bersarang, menjadi satu.
Sebelum:
for (i=0; i<a; i++) foo();
for (i=0; i<b; i++) bar();
@ kaoD, dalam kedua kasus foodisebut awaktu, bardisebut bwaktu. Ini karena dalam "setelah", loop berjalan a+bkali, apanggilan pertama foo, panggilan berikutnya bar.
ugoren
Saya melihat ini lagi (jauh, jauh kemudian), dan saya tidak mengerti pertanyaan saya sendiri sekarang. Saya mungkin tidak mengerti operasi ternary sebelumnya? Cara saya melihatnya sekarang, masuk akal.
Gaffi
1
Woops, saya membaca itu sangat larut malam. Kamu benar!
kaoD
3
Sangat mirip: for(y=0;y<Y;++y)for(x=0;x<X;++x)sering kali menjadi for(i=0;i<X*Y;++i)dengan xdigantikan oleh i%Xdan ydigantikan oleh i/X.
Lynn
62
Hanya untuk menyebutkan yang sudah jelas:
Pertanyakan pilihan algoritma Anda dan coba sesuatu yang sama sekali baru.
Ketika bermain golf (terutama masalah yang lebih sulit yang mengakibatkan program lebih lama) terlalu sering Anda mungkin tetap pada jalur yang Anda pilih pertama kali tanpa mencoba opsi mendasar lainnya. Tentu saja, Anda dapat bermain golf mikro satu atau beberapa baris sekaligus atau sebagian dari keseluruhan gagasan, tetapi seringkali tidak mencoba solusi yang sama sekali berbeda.
Ini terutama terlihat di Hitting 495 (Kaprekar) di mana menyimpang dari algoritma yang sebenarnya dan mencari pola yang dapat Anda terapkan untuk mendapatkan hasil yang sama lebih pendek dalam banyak bahasa (hanya bukan J).
Kelemahannya adalah Anda mungkin memecahkan hal yang sama setengah lusin kali. Tapi itu benar-benar bekerja di semua bahasa kecuali HQ9 + (di mana menemukan cara lain untuk menghasilkan Hello World akan sedikit sia-sia).
+1 Selain bagus untuk bermain golf, ini adalah latihan yang bagus untuk setiap programmer dalam banyak situasi dunia nyata!
Gaffi
52
Gunakan Pengembangan Test-Driven
Jika kode harus menangani berbagai input, maka tulis tes komprehensif dan membuatnya mudah untuk menjalankan semuanya dengan sangat cepat. Ini memungkinkan Anda untuk mencoba mengubah langkah bayi berisiko satu per satu. Golf kemudian menjadi seperti refactoring dengan niat jahat.
Saya menggunakan spin-off dari metode ini. Karena masalahnya sendiri biasanya agak sederhana, saya menulis sebuah program yang melakukan pekerjaan. Biasanya ini "golf bisa dibaca", sehingga ringkas, tetapi ada baris baru dll. Saya menyalin file ini ke lokasi baru dan memutarnya, memeriksa setiap sekarang dan kemudian bahwa program mengembalikan nilai yang sama untuk beberapa input yang dipilih. Jika saya membuat kesalahan meninggalkan saya dengan program yang rusak, tidak ada ingatan tentang apa yang saya ubah dan tidak ada pemahaman tentang karya golf saya, saya memiliki "spesifikasi" yang disimpan sebagai sumber referensi.
shiona
2
Saya suka metode ini, yang merupakan salah satu alasan mengapa saya cenderung memasukkan test suite komprehensif untuk semua masalah yang saya tulis.
Joey
@RubberDuck Prinsip Jangan ulangi diri sendiri sering diikuti dengan ketat.
Jonathan Frech
48
Cobalah untuk mengurangi pernyataan logis
Misalnya, jika Adan Bboolean dan bahasa Anda memperlakukan boolean seperti angka sampai batas tertentu, A and (not B)dan A>Bsetara. Misalnya dengan Python
B>A or foo()akan menjadi cara yang lebih singkat untuk mengungkapkan ini, manfaatkan evaluasi malas ekspresi boolean untuk memastikan hanya menghitung hal-hal yang diperlukan.
scragar
5
@scagar: Benar, tapi ini bukan poin dari tip ini. (Ini adalah tip independen yang berharga.)
Wrzlprmft
3
@scagar, B>A or fooakan mengevaluasi foojika B==Aitu bukan yang kita inginkan. (Benar?)
msh210
2
Juga, jika Anda memiliki kondisi
berlarut
33
Inisialisasi variabel menggunakan nilai yang sudah Anda miliki.
Alih-alih x=1, coba cari sesuatu yang sudah sama dengan 1.
Misalnya, nilai pengembalian fungsi: printf("..");x=0;-> x=!printf("..");. Ini paling mudah dengan 0, karena Anda selalu dapat meniadakan, atau ketika semua yang Anda butuhkan adalah nilai kebenaran yang benar (dan tidak peduli apakah itu 1 atau 19).
@ std''OrgnlDave, Benar, tetapi pertanyaan ini adalah tentang hal-hal yang umum untuk semua bahasa.
ugoren
33
Gunakan unary ~untuk x+1danx-1
Trik ini berlaku untuk bahasa yang memiliki operator negasi bitwise unary ~dan operator negasi reguler unary -.
Jika program Anda, secara kebetulan, berisi ekspresi -x-1, Anda dapat menggantinya dengan ~xuntuk menyimpan byte. Ini tidak terlalu sering terjadi, tetapi perhatikan apa yang terjadi jika kita meniadakan ( -) kedua ekspresi: x+1sama dengan -~x! Demikian pula, x-1sama ~-x. (Pikirkan ke arah mana tilde menunjuk: kanan adalah +, kiri adalah -.)
Ini berguna, karena dalam semua bahasa saya bisa memikirkan yang memiliki operator ini, mereka memiliki prioritas lebih tinggi daripada kebanyakan operator. Ini memungkinkan Anda menghemat tanda kurung. Tonton bagaimana kami menyimpan empat byte di sini:
Ketahui aturan untuk spasi putih dalam bahasa Anda. Beberapa tanda baca, atau karakter lain, mungkin tidak memerlukan spasi putih di sekitarnya. Pertimbangkan fungsi shell Bourne ini :
f () { echo a; echo b; }
Dalam Bourne shell, ();adalah metacharacters, dan tidak perlu mengelilingi spasi putih. Namun, {}adalah kata-kata dan perlu spasi putih kecuali mereka di sebelah karakter metak. Kita dapat bermain golf sejauh 4 ruang di sebelah ();, tetapi harus menjaga jarak antara {dan echo.
f(){ echo a;echo b;}
Dalam Common Lisp dan PicoLisp , ()adalah karakter metachar . Pertimbangkan kode ini untuk menemukan rata-rata dua angka:
(/ (+ a b) 2)
Kami dapat bermain golf 2 ruang.
(/(+ a b)2)
Beberapa bahasa memiliki aturan aneh dan halus untuk spasi putih. Pertimbangkan program Ruby ini, yang mencetak jumlah dan produk dari linier bilangan bulat.
Masing-masing &membutuhkan ruang sebelum dirinya sendiri. Di Ruby, i=$F.map &:to_iberarti di i=$F.map(&:to_i)mana &melewati parameter blok. Tapi, i=$F.map&:to_iberarti di i=$F.map.&(:to_i)mana &operator biner.
Keanehan ini terjadi dalam bahasa, seperti Perl atau Ruby, yang menggunakan tanda baca yang ambigu. Jika ragu, gunakan REPL atau tulis program pendek untuk menguji aturan spasi putih.
Mengapa harus ada spasi antara "{" dan "echo", tetapi tidak antara ";" dan "gema"?
Ryan
3
Saya menggunakan istilah-istilah dari manual untuk OpenBSD sh (1), yang mengatakan bahwa "{" adalah kata yang dilindungi undang-undang dan ";" adalah meta-karakter. Karena itu, "{echo" adalah satu kata tetapi "; echo" adalah dua kata. Manual lain mungkin menjelaskan hal ini secara berbeda. Juga, z shell zsh memiliki aturan berbeda.
kernigh
28
menugaskan fungsi nama baru jika digunakan beberapa kali
x = SomeLongFunctionName
x(somedata)
x(somemoredata)
etc
Hanya jika kita menggunakan cukup banyak panggilan x.
elipszilon
28
Nama Variabel Huruf Tunggal
Anda memiliki 52 dari mereka; gunakan semuanya! Jangan takut untuk mencoba pendekatan yang berbeda dan membandingkan panjangnya. Ketahui bahasa dan fungsi pintas / pustaka tertentu yang tersedia.
Seringkali $dan _dapat digunakan sebagai pengidentifikasi.
Griffin
4
@ Gaffi: Dan lebih dari cukup untuk bahasa yang memungkinkan pengidentifikasi Unicode, kecuali tugas tersebut membatasi Anda untuk ASCII atau menghitung byte daripada karakter.
hammar
Jika Anda menghitung byte alih-alih unicode, maka menggunakan extended ascii mungkin merupakan cara untuk memeras ~ 120 pengidentifikasi lainnya jika Anda memerlukannya (bukan untuk skrip golf, Anda harus memerlukan lebih dari 26)
scragar
2
@adalah nama variabel yang valid di T-SQL, gunakan saja @a.
BradC
25
Gunakan operator kondisional.
Operator bersyarat
bool ? condition_true : condition_false
lebih bermanfaat, lebih bijak daripada pernyataan IF .
Bahasa yang tidak memiliki terner dapat digunakan a&&b||csebagai gantinya. Sedikit lebih lama, tetapi masih lebih pendek dari if.
Michael Kohl
Kemudian lagi, beberapa tidak dapat menggunakan salah satu opsi (VBA datang ke pikiran), tetapi keduanya masih merupakan saran yang baik. :-)
Gaffi
1
Gaffi: VBA memiliki Iff, meskipun itu adalah fungsi, jadi harus dievaluasi semua argumen.
Joey
Menggunakan terner di jika pernyataan juga bisa sangat membantuif(a ? b : c)
Jojodmo
4
@MichaelKohl perhatikan bahwa a&&b||cdapat kembali ckapan abenar iff bsalah, sedikit kasus, tapi kita tidak boleh lupa bahwa ^^
Katenkyo
24
Tuliskan penjelasan tentang kode Anda
Menulis penjelasan memaksa Anda untuk secara menyeluruh melihat setiap bagian dari kode Anda lagi dan membuat pemikiran dan pilihan Anda dalam menulis suatu bagian tertentu secara eksplisit. Dengan melakukan itu, Anda mungkin menemukan bahwa pendekatan yang berbeda dimungkinkan yang dapat menghemat beberapa byte, atau bahwa Anda secara tidak sadar membuat asumsi yang tidak selalu berlaku.
Kedengarannya seperti no-brainer, tetapi dengan berhati-hati Anda mungkin dapat "menyelamatkan" beberapa karakter dengan tidak benar-benar melakukan apa pun!
Jika Anda menggunakan Windows, Anda mungkin memasukkan \r\nbukan hanya \ratau \nketika Anda menekan Return - menambahkan byte tambahan per baris! Putar karakter kontrol hanya untuk mengecek Anda tidak melakukan ini.
Di Notepad ++ Anda dapat mengonversi semua \r\nujung baris menjadi hanya \rdengan masuk ke Edit > EOL Conversion > UNIX/OSX Format.
Pastikan juga Anda tidak memasukkan spasi spasi tambahan dalam jumlah karakter Anda! Umpan baris pada baris terbawah dalam kode Anda juga tidak penting, sehingga tidak perlu dihitung juga.
Saya tidak berpikir saya pernah melihat sebuah kasus di mana ini sebenarnya dihitung ...
Yakub
4
Saya baru saja mengalami masalah ini sendiri (karenanya mengapa saya menambahkannya).
Sean Latham
21
Baca pertanyaan dengan seksama
Code golfing adalah tentang memahami pertanyaan (apa yang ditanyakan dan apa yang tidak ditanyakan, meskipun itu akan tersirat dalam pengaturan lain) seperti memproduksi kode yang (mungkin) hanya memuaskan apa yang ditanyakan.
Masukan apa pun selain apa yang diminta secara eksplisit tidak perlu ditangani. Jika ada beberapa kasus uji dan tidak ada persyaratan umum, kode Anda hanya dapat berfungsi dalam kasus tersebut. Dll
Saya pikir judul yang lebih baik di sini adalah "Jangan menangani kasus tepi yang tidak diperlukan". Ungkapan "Cobalah untuk menemukan celah" mengingatkan cara untuk menghindari melakukan apa yang ditentukan melalui beberapa reinterpretasi yang cerdas dari aturan, sedangkan apa yang Anda tawarkan hanyalah nasihat yang baik untuk tidak terlalu menerapkan solusi Anda.
Jonathan Van Matre
1
Ya, tetapi penafsiran ulang yang cerdas atas aturan juga merupakan bagian dari kode golf! (0 solusi arang, dll.)
Tobia
8
Namun itu akan menjadi jawaban yang berbeda. Ada perbedaan mendasar antara, misalnya, menerapkan solusi yang hanya berfungsi untuk int karena OP tidak memerlukan dukungan float, dan jawaban yang mencetak teks "lebih besar dari 100" karena "Anda tidak mengatakan itu harus menjadi bilangan prima aktual ".
Jonathan Van Matre
Saya pikir beberapa OP termasuk pemberitahuan "Kasus uji dapat berubah; kode Anda masih harus bekerja setelah perubahan" pemberitahuan, dan benar-benar mengubahnya jika mereka melihat hanya satu jawaban yang mengkode kode pengujian.
Erik the Outgolfer
20
Gunakan operasi bitwise untuk memeriksa angka antara 0 dan 2 n -1
Mungkin ada sedikit kasus tepi, tetapi kadang-kadang bisa berguna. Itu bergantung pada fakta bahwa semua angka yang m = 2 n -1 berlaku memiliki n bit paling kanan diatur ke 1.
Caranya adalah x&~m. Ini akan kembali benar setiap kali xadalah tidak antara 0 dan m(inklusif), dan false jika tidak. Menghemat 6 byte dari persamaan ekuivalen terpendek berikutnya:, x>=0&&x<=mtetapi jelas hanya berfungsi ketika mmemenuhi 2 n -1.
Sebagai contoh, di C, fungsi utama Anda selalu memberikan jumlah argumen yang disediakan untuk program (yaitu 1 - nama program - secara 'default') sehingga main(i){...Anda sekarang memiliki variabel dengan nilai 1 tanpa harus melakukan tugas apa pun. 2 karakter tersimpan di sana ..
Griffin
6
Saya pikir itu cukup spesifik untuk bahasa C. Script tidak perlu deklarasi, dan dalam kebanyakan bahasa yang dikompilasi mendefinisikan variabel tidak lebih dari mendefinisikan parameter.
ugoren
di java ketika membutuhkan array di dalam fungsi yang memiliki tipe yang sama dengan satu parameter Anda dapat menghemat beberapa byte dengan menempatkan parameter itu sebagai yang terakhir dan menjadikannya sebagai parameter vararg; (Digunakan untuk memangkas beberapa byte pada fungsi untuk menemukan kata terpanjang dalam kalimat)
Saya tidak yakin saya mengerti maksudnya. Dari apa ini dikurangi?
Gaffi
@Gaffi Anda menyimpan satu karakter dan mereka melakukan hal yang sama
ajax333221
vs alternatif apa? Maaf, tidak berusaha keras kepala, saya hanya tidak mengerti. (newb, ini, rupanya ...)
Gaffi
1
Ah, begitu. Bekerja pada transisi integer dari 9 ke 10, 99 ke 100, dll. Maaf, butuh waktu lama! (Saya katakan bilangan bulat saja, karena saya dapat melihat masalah dengan n = 9,5 ...)
Gaffi
8
Juga dalam beberapa bahasa (jika didukung) jika angka Anda besar / cukup kecil notasi ilmiah sebenarnya dapat menyelamatkan Anda beberapa karakter sebagai gantinya: if(n>99999)vsif(n<1e5)
scragar
16
Gunakan> dan <sebagai ganti> = dan <=
Saat memeriksa nilai integer yang dikodekan dengan keras, gunakan >dan <alih-alih >=dan <=jika memungkinkan. Misalnya, menggunakan
Terkait: Jika Anda yakin suatu hasil tidak boleh negatif, Anda bisa menggunakan <1sebagai gantinya ==0sebagai cek-nol (atau >0bukan !=0untuk cek cermin).
Kevin Cruijssen
1
Bukankah seharusnya Anda menambahkan catatan tentang xmenjadi bilangan bulat?
Zacharý
15
Hindari jeda lingkaran prematur
Jika menjalankan melalui loop untuk memeriksa 1 atau lebih contoh dari boolean check, itu mungkin membuat program yang lebih efisien untuk keluar dari loop pada nilai true pertama. Namun, menghapus break dan looping melalui semua iterasi memungkinkan kode yang lebih pendek
int main() {
bool m = false;
int n = 1000;
for (int i = 0; i < n; i++) {
if (i >= 100) {
m = true;
break; // remove this line
}
}
return 0;
}
Anda juga dapat menyederhanakan ifpernyataan diri dalam kasus ini: m|=i>=100. (Dan Anda juga dapat menyederhanakan i>=100untuk i>99dalam hal ini tapi itu tidak sangat relevan di sini)
marinus
15
gunakan -sebagai ganti!=
untuk perbandingan numerik:
Jika a sama dengan b, a-bmenghasilkan 0, yang salah. Apa pun selain 0kebenaran; jadi
jika digunakan dalam konteks boolean, a-b<=>a!=b
Jika Anda menggunakannya dengan if/elseatau dengan operator ternary, ini juga dapat menghemat satu byte untuk kesetaraan: a==b?c:d<=>a-b?d:c
Sebagian besar bahasa memiliki cara untuk membagi string menjadi array string di sekitar token. Ini pasti akan lebih pendek dari array literal begitu panjangnya mencapai ambang tergantung pada bahasa, karena overhead tambahan per string akan menjadi satu salinan token satu char daripada satu (setidaknya) dua pembatas string.
Misalnya dalam GolfScript
["Foo""Bar""Baz""Quux"] # 23 chars
menjadi
"Foo
Bar
Baz
Quux"n/ # 20 chars
Untuk beberapa bahasa, ambangnya serendah satu string. Misal di Jawa,
Pengecualian adalah Ruby, yang menyediakan sebuah array-of-string literal yang secara otomatis membagi pada ruang pada biaya dua byte: %w{Foo Bar Baz Quux}.
Martin Ender
1
Perl menyediakan sesuatu yang serupa: qw(Foo Bar Baz Quux)menjadi daftar string.
BenGoldberg
12
Pahami apa yang dilakukan orang lain
Selain menyenangkan, jika Anda memeriksa kode orang lain, Anda kadang-kadang dapat menemukan algoritma yang baik yang tidak Anda pikirkan, atau trik (kadang-kadang yang jelas) yang Anda abaikan.
Terkadang ada jawaban yang sudah ada yang bisa Anda terjemahkan ke bahasa lain, dan manfaatkan dari kebaikan bahasa lainnya.
Setiap kali Anda menggabungkan beberapa ekspresi, periksa tabel diutamakan operator untuk bahasa Anda untuk melihat apakah Anda dapat memesan ulang barang untuk menghemat tanda kurung.
Contoh:
Dalam semua bahasa yang saya tahu, operator bitwise memiliki prioritas lebih tinggi daripada operator boolean:
(a&b)&&ctidak perlu tanda kurung: a&b&&csama seperti (a*b)+ctidak.
a+(b<<c)dapat ditulis ulang sebagai a+b*2**c.
Itu tidak menyimpan apa pun untuk contoh ini, tetapi itu akan jika cadalah integer literal kecil (<14).
Operasi bitwise memiliki prioritas lebih rendah daripada kebanyakan operasi aritmatika, jadi jika bahasa Anda secara implisit melemparkan boolean ke int, Anda dapat menyimpan byte a<b&&c<ddengan a<b&c<d(kecuali jika Anda memerlukan evaluasi hubung singkat)
Jika Anda memiliki Xpernyataan {di dalam }for-loop Anda, Anda bisa memindahkan X-1pernyataan (di )dalam for-loop setelah tanda koma kedua for(blah;blah;HERE)untuk menghemat 3 byte. (pisahkan pernyataan dengan menggunakan koma ,)
Dari pada
for(int i=0;i<9;){s+=s.length();println(i++);}
Anda dapat memindahkan salah satu pernyataan ke (kawat gigi for-loop )sambil meninggalkan yang lainnya
for(int i=0;i<9;println(i++))s+=s.length();
dan simpan 3 byte (disimpan 1 byte lagi berkat @ETHProductions)
Sederhananya,
dari pada
for(blah;blah;){blah 1;blah 2;...;blah X}
pindahkan pernyataan di sekitar sehingga Anda berakhir dengan ini
Ini mungkin terlihat seperti tip yang tidak akan sering Anda gunakan, agak seperti menggunakan ~xbukannya -x-1tidak sering terjadi, tetapi saya sudah cukup sering menggunakannya untuk melihatnya sebagai tip yang bermanfaat di sini. Terutama dengan pengindeksan array Anda dapat menggunakan ini di atas dalam beberapa kasus.
Trik sederhana yang saya buat ketika mencoba untuk memeras kondisi panjang dirantai oleh ands (atau ors, dalam hal ini hanya mengganti 'semua' dengan 'apa saja').
Bahasa apa yang memiliki all(array-of-Booleans)built-in?
Peter Taylor
3
Ruby memilikinya. [a>0,a<10,a+b==4,a+3<1].all?
kernigh
4
Meskipun jika ini adalah Python, Anda akan menggunakan sesuatu sepertiif 10>a>0 and a+b==4>1>a+3:
Sp3000
@PeterTaylor Haskell juga
bangga haskeller
6
Mengandalkan kompiler untuk memberikan kinerja yang diperlukan.
Pastikan untuk mengetahui optimisasi mana yang dijamin oleh kompiler dan pada level optimasi mana, dan gunakan secara bebas. Dan bahkan jika kinerja bukan persyaratan perhatian , Anda masih dapat menguji dengan optimisasi, dan kemudian hanya mendiskon satu karakter karena kode Anda secara teknis masih valid tanpa flag compiler.
Pertimbangkan fungsi Haskell berikut untuk menghitung 2 ^ n (mengabaikan fakta bahwa Haskell sudah memiliki satu atau tiga operator eksponensial bawaan) (23 karakter):
p 0=1;p x=p(x-1)+p(x-1)
Masalahnya - sangat lambat, berjalan dalam waktu yang eksponensial. Ini mungkin membuat kode Anda tidak dapat diuji atau untuk gagal kendala kinerja yang diberikan oleh pertanyaan. Anda mungkin tergoda untuk menggunakan variabel sementara atau fungsi literal yang segera dipanggil untuk menghindari panggilan fungsi berulang (25 karakter):
p 0=1;p x=(\y->y+y)$p$x-1
Tetapi kompiler sudah dapat melakukan itu untuk Anda, Anda hanya perlu menetapkan -Osebagai flag kompiler! Alih-alih menghabiskan beberapa karakter tambahan per situs untuk menghilangkan sub-ekspresi umum secara manual, katakan saja kepada kompiler untuk melakukan optimasi dasar bagi Anda untuk total satu atau dua karakter di seluruh program.
Dalam bahasa apa Anda bisa melakukan tugas di dalam suatu panggilan? atau apakah itu kata kunci arg?
kucing
2
Saya pikir penugasan adalah ekspresi (dengan nilai baru variabel yang ditugaskan sebagai nilai ekspresi mereka) dalam setidaknya C, C ++, C #, dan Java. a = (b=c)+1;set bke c, dan kemudian set ake b+1.
Lynn
@Lynn Coba a=1+b=c. Dan Anda dapat menambahkan PHP dan JavaScript ke daftar Anda.
Titus
2
Ruby melakukan yang terbaik. Ini memberi =operator prioritas lebih tinggi di sebelah kiri daripada di sebelah kanan, sehingga 1+x=2berlaku dan dievaluasi menjadi3
Cyoce
@Cyoce afaik seperti itu dalam semua bahasa di mana tugas adalah ekspresi.
Titus
5
Memanfaatkan versi bahasa / kompiler / kebiasaan lingkungan / fitur baru
Ini sangat berguna untuk polyglot , tetapi dapat diterapkan untuk tantangan lain. Kadang-kadang, bug penyusun dapat memangkas byte, bug implementasi dapat memungkinkan Anda untuk menyimpan beberapa karakter, atau fitur yang benar-benar canggih dapat meningkatkan skor Anda.
Juga, gunakan conditional bitty ( &, `|) untuk menghapus lebih banyak karakter.
FUZxxl
2
Meskipun menggunakan bitwise &bukannya &&menghilangkan 1 karakter dalam beberapa kasus itu mengacaukan prioritas operator dan Anda harus meletakkan tanda kurung untuk membuatnya bekerja. Gunakan dengan bijak.
DollarAkshay
4
Temukan cara yang lebih baik untuk menginisialisasi variabel Anda
Beberapa jawaban lain hampir menyebutkan hal ini, tetapi dalam banyak bahasa (diketik dengan ketat?), Lebih pendek untuk diinisialisasi xsebagai string kosong seperti:
x:=""
atau xsebagai rune kosong (char) seperti:
x:=''
dari
var x string
dan
var x rune
Menggunakan nilai yang sudah ada sebelumnya jelas lebih disukai, tetapi tidak begitu mudah.
<all languages>
...Jawaban:
Gabungkan Loop
Anda biasanya dapat menggabungkan dua loop konsekuen, atau dua loop bersarang, menjadi satu.
Sebelum:
Setelah:
sumber
foo
disebuta
waktu,bar
disebutb
waktu. Ini karena dalam "setelah", loop berjalana+b
kali,a
panggilan pertamafoo
, panggilan berikutnyabar
.for(y=0;y<Y;++y)for(x=0;x<X;++x)
sering kali menjadifor(i=0;i<X*Y;++i)
denganx
digantikan olehi%X
dany
digantikan olehi/X
.Hanya untuk menyebutkan yang sudah jelas:
Pertanyakan pilihan algoritma Anda dan coba sesuatu yang sama sekali baru.
Ketika bermain golf (terutama masalah yang lebih sulit yang mengakibatkan program lebih lama) terlalu sering Anda mungkin tetap pada jalur yang Anda pilih pertama kali tanpa mencoba opsi mendasar lainnya. Tentu saja, Anda dapat bermain golf mikro satu atau beberapa baris sekaligus atau sebagian dari keseluruhan gagasan, tetapi seringkali tidak mencoba solusi yang sama sekali berbeda.
Ini terutama terlihat di Hitting 495 (Kaprekar) di mana menyimpang dari algoritma yang sebenarnya dan mencari pola yang dapat Anda terapkan untuk mendapatkan hasil yang sama lebih pendek dalam banyak bahasa (hanya bukan J).
Kelemahannya adalah Anda mungkin memecahkan hal yang sama setengah lusin kali. Tapi itu benar-benar bekerja di semua bahasa kecuali HQ9 + (di mana menemukan cara lain untuk menghasilkan Hello World akan sedikit sia-sia).
sumber
Gunakan Pengembangan Test-Driven
Jika kode harus menangani berbagai input, maka tulis tes komprehensif dan membuatnya mudah untuk menjalankan semuanya dengan sangat cepat. Ini memungkinkan Anda untuk mencoba mengubah langkah bayi berisiko satu per satu. Golf kemudian menjadi seperti refactoring dengan niat jahat.
sumber
Cobalah untuk mengurangi pernyataan logis
Misalnya, jika
A
danB
boolean dan bahasa Anda memperlakukan boolean seperti angka sampai batas tertentu,A and (not B)
danA>B
setara. Misalnya dengan Pythonsama dengan:
sumber
B>A or foo()
akan menjadi cara yang lebih singkat untuk mengungkapkan ini, manfaatkan evaluasi malas ekspresi boolean untuk memastikan hanya menghitung hal-hal yang diperlukan.B>A or foo
akan mengevaluasifoo
jikaB==A
itu bukan yang kita inginkan. (Benar?)Inisialisasi variabel menggunakan nilai yang sudah Anda miliki.
Alih-alih
x=1
, coba cari sesuatu yang sudah sama dengan 1.Misalnya, nilai pengembalian fungsi:
printf("..");x=0;
->x=!printf("..");
. Ini paling mudah dengan 0, karena Anda selalu dapat meniadakan, atau ketika semua yang Anda butuhkan adalah nilai kebenaran yang benar (dan tidak peduli apakah itu 1 atau 19).sumber
Gunakan unary
~
untukx+1
danx-1
Trik ini berlaku untuk bahasa yang memiliki operator negasi bitwise unary
~
dan operator negasi reguler unary-
.Jika program Anda, secara kebetulan, berisi ekspresi
-x-1
, Anda dapat menggantinya dengan~x
untuk menyimpan byte. Ini tidak terlalu sering terjadi, tetapi perhatikan apa yang terjadi jika kita meniadakan (-
) kedua ekspresi:x+1
sama dengan-~x
! Demikian pula,x-1
sama~-x
. (Pikirkan ke arah mana tilde menunjuk: kanan adalah+
, kiri adalah-
.)Ini berguna, karena dalam semua bahasa saya bisa memikirkan yang memiliki operator ini, mereka memiliki prioritas lebih tinggi daripada kebanyakan operator. Ini memungkinkan Anda menghemat tanda kurung. Tonton bagaimana kami menyimpan empat byte di sini:
sumber
Peras ruang putih
Ketahui aturan untuk spasi putih dalam bahasa Anda. Beberapa tanda baca, atau karakter lain, mungkin tidak memerlukan spasi putih di sekitarnya. Pertimbangkan fungsi shell Bourne ini :
Dalam Bourne shell,
();
adalah metacharacters, dan tidak perlu mengelilingi spasi putih. Namun,{}
adalah kata-kata dan perlu spasi putih kecuali mereka di sebelah karakter metak. Kita dapat bermain golf sejauh 4 ruang di sebelah();
, tetapi harus menjaga jarak antara{
danecho
.Dalam Common Lisp dan PicoLisp ,
()
adalah karakter metachar . Pertimbangkan kode ini untuk menemukan rata-rata dua angka:Kami dapat bermain golf 2 ruang.
Beberapa bahasa memiliki aturan aneh dan halus untuk spasi putih. Pertimbangkan program Ruby ini, yang mencetak jumlah dan produk dari linier bilangan bulat.
Masing-masing
&
membutuhkan ruang sebelum dirinya sendiri. Di Ruby,i=$F.map &:to_i
berarti dii=$F.map(&:to_i)
mana&
melewati parameter blok. Tapi,i=$F.map&:to_i
berarti dii=$F.map.&(:to_i)
mana&
operator biner.Keanehan ini terjadi dalam bahasa, seperti Perl atau Ruby, yang menggunakan tanda baca yang ambigu. Jika ragu, gunakan REPL atau tulis program pendek untuk menguji aturan spasi putih.
sumber
menugaskan fungsi nama baru jika digunakan beberapa kali
sumber
x
.Nama Variabel Huruf Tunggal
Anda memiliki 52 dari mereka; gunakan semuanya! Jangan takut untuk mencoba pendekatan yang berbeda dan membandingkan panjangnya. Ketahui bahasa dan fungsi pintas / pustaka tertentu yang tersedia.
sumber
$
dan_
dapat digunakan sebagai pengidentifikasi.@
adalah nama variabel yang valid di T-SQL, gunakan saja@a
.Gunakan operator kondisional.
Operator bersyarat
lebih bermanfaat, lebih bijak daripada pernyataan IF .
dapat ditulis sebagai
sumber
a&&b||c
sebagai gantinya. Sedikit lebih lama, tetapi masih lebih pendek dariif
.Iff
, meskipun itu adalah fungsi, jadi harus dievaluasi semua argumen.if(a ? b : c)
a&&b||c
dapat kembalic
kapana
benar iffb
salah, sedikit kasus, tapi kita tidak boleh lupa bahwa ^^Tuliskan penjelasan tentang kode Anda
Menulis penjelasan memaksa Anda untuk secara menyeluruh melihat setiap bagian dari kode Anda lagi dan membuat pemikiran dan pilihan Anda dalam menulis suatu bagian tertentu secara eksplisit. Dengan melakukan itu, Anda mungkin menemukan bahwa pendekatan yang berbeda dimungkinkan yang dapat menghemat beberapa byte, atau bahwa Anda secara tidak sadar membuat asumsi yang tidak selalu berlaku.
Tip ini mirip dengan Pertanyaan algoritma pilihan Anda dan coba sesuatu yang sama sekali baru ; Namun, saya telah menemukan bahwa langkah untuk benar-benar menuliskan bagaimana setiap bagian seharusnya bekerja kadang-kadang penting untuk menjadi sadar akan alternatif.
Sebagai bonus, jawaban termasuk penjelasan lebih menarik bagi pengguna lain dan karenanya lebih cenderung untuk di-upgrade.
sumber
Periksa jumlah karakter Anda
Kedengarannya seperti no-brainer, tetapi dengan berhati-hati Anda mungkin dapat "menyelamatkan" beberapa karakter dengan tidak benar-benar melakukan apa pun!
Jika Anda menggunakan Windows, Anda mungkin memasukkan
\r\n
bukan hanya\r
atau\n
ketika Anda menekan Return - menambahkan byte tambahan per baris! Putar karakter kontrol hanya untuk mengecek Anda tidak melakukan ini.Di Notepad ++ Anda dapat mengonversi semua
\r\n
ujung baris menjadi hanya\r
dengan masuk keEdit > EOL Conversion > UNIX/OSX Format
.Pastikan juga Anda tidak memasukkan spasi spasi tambahan dalam jumlah karakter Anda! Umpan baris pada baris terbawah dalam kode Anda juga tidak penting, sehingga tidak perlu dihitung juga.
sumber
Baca pertanyaan dengan seksama
Code golfing adalah tentang memahami pertanyaan (apa yang ditanyakan dan apa yang tidak ditanyakan, meskipun itu akan tersirat dalam pengaturan lain) seperti memproduksi kode yang (mungkin) hanya memuaskan apa yang ditanyakan.
Masukan apa pun selain apa yang diminta secara eksplisit tidak perlu ditangani. Jika ada beberapa kasus uji dan tidak ada persyaratan umum, kode Anda hanya dapat berfungsi dalam kasus tersebut. Dll
sumber
Gunakan operasi bitwise untuk memeriksa angka antara 0 dan 2 n -1
Mungkin ada sedikit kasus tepi, tetapi kadang-kadang bisa berguna. Itu bergantung pada fakta bahwa semua angka yang m = 2 n -1 berlaku memiliki n bit paling kanan diatur ke 1.
Jadi, 7 10 == 00000111 2 , 15 10 == 00001111 2 , 31 10 == 00011111 2 dan seterusnya.
Caranya adalah
x&~m
. Ini akan kembali benar setiap kalix
adalah tidak antara 0 danm
(inklusif), dan false jika tidak. Menghemat 6 byte dari persamaan ekuivalen terpendek berikutnya:,x>=0&&x<=m
tetapi jelas hanya berfungsi ketikam
memenuhi 2 n -1.sumber
Gunakan kembali parameter fungsi, bukan variabel baru
sumber
main(i){...
Anda sekarang memiliki variabel dengan nilai 1 tanpa harus melakukan tugas apa pun. 2 karakter tersimpan di sana ..Lebih besar / kurang dari untuk menyimpan digit:
Hanya ingat untuk menukar kode dari
if
keelse
dan mereka akan melakukan hal yang persis sama (atau mengganti sisi ketidaksetaraan)!Catatan: ini dapat diterapkan dengan kekuatan 10 dan negatifnya:
...-100, -10, 10, 100...
(tautan sumber)
sumber
if(n>99999)
vsif(n<1e5)
Gunakan> dan <sebagai ganti> = dan <=
Saat memeriksa nilai integer yang dikodekan dengan keras, gunakan
>
dan<
alih-alih>=
dan<=
jika memungkinkan. Misalnya, menggunakanLebih pendek 2 byte daripada menggunakan
sumber
<1
sebagai gantinya==0
sebagai cek-nol (atau>0
bukan!=0
untuk cek cermin).x
menjadi bilangan bulat?Hindari jeda lingkaran prematur
Jika menjalankan melalui loop untuk memeriksa 1 atau lebih contoh dari boolean check, itu mungkin membuat program yang lebih efisien untuk keluar dari loop pada nilai true pertama. Namun, menghapus break dan looping melalui semua iterasi memungkinkan kode yang lebih pendek
sumber
if
pernyataan diri dalam kasus ini:m|=i>=100
. (Dan Anda juga dapat menyederhanakani>=100
untuki>99
dalam hal ini tapi itu tidak sangat relevan di sini)gunakan
-
sebagai ganti!=
untuk perbandingan numerik:
Jika a sama dengan b,
a-b
menghasilkan0
, yang salah. Apa pun selain0
kebenaran; jadijika digunakan dalam konteks boolean,
a-b
<=>a!=b
Jika Anda menggunakannya dengan
if/else
atau dengan operator ternary, ini juga dapat menghemat satu byte untuk kesetaraan:a==b?c:d
<=>a-b?d:c
sumber
Pisahkan string untuk array panjang
Sebagian besar bahasa memiliki cara untuk membagi string menjadi array string di sekitar token. Ini pasti akan lebih pendek dari array literal begitu panjangnya mencapai ambang tergantung pada bahasa, karena overhead tambahan per string akan menjadi satu salinan token satu char daripada satu (setidaknya) dua pembatas string.
Misalnya dalam GolfScript
menjadi
Untuk beberapa bahasa, ambangnya serendah satu string. Misal di Jawa,
menjadi
sumber
%w{Foo Bar Baz Quux}
.qw(Foo Bar Baz Quux)
menjadi daftar string.Pahami apa yang dilakukan orang lain
Selain menyenangkan, jika Anda memeriksa kode orang lain, Anda kadang-kadang dapat menemukan algoritma yang baik yang tidak Anda pikirkan, atau trik (kadang-kadang yang jelas) yang Anda abaikan.
Terkadang ada jawaban yang sudah ada yang bisa Anda terjemahkan ke bahasa lain, dan manfaatkan dari kebaikan bahasa lainnya.
sumber
tahu prioritas operator Anda
Setiap kali Anda menggabungkan beberapa ekspresi, periksa tabel diutamakan operator untuk bahasa Anda untuk melihat apakah Anda dapat memesan ulang barang untuk menghemat tanda kurung.
Contoh:
(a&b)&&c
tidak perlu tanda kurung:a&b&&c
sama seperti(a*b)+c
tidak.a+(b<<c)
dapat ditulis ulang sebagaia+b*2**c
.Itu tidak menyimpan apa pun untuk contoh ini, tetapi itu akan jika
c
adalah integer literal kecil (<14).a<b&&c<d
dengana<b&c<d
(kecuali jika Anda memerlukan evaluasi hubung singkat)sumber
Lebih pendek untuk-loop
Jika Anda memiliki
X
pernyataan{
di dalam}
for-loop Anda, Anda bisa memindahkanX-1
pernyataan(
di)
dalam for-loop setelah tanda koma keduafor(blah;blah;HERE)
untuk menghemat 3 byte. (pisahkan pernyataan dengan menggunakan koma,
)Dari pada
Anda dapat memindahkan salah satu pernyataan ke
(
kawat gigi for-loop)
sambil meninggalkan yang lainnyadan simpan 3 byte (disimpan 1 byte lagi berkat @ETHProductions)
Sederhananya,
dari pada
pindahkan pernyataan di sekitar sehingga Anda berakhir dengan ini
dan simpan 3 byte
sumber
for
adalah pernyataan terakhir, itu;
menjadi opsionalGunakan unary
~
untuka-b-1
dana+b+1
Selain saran @ Lynn tentang
x+1
→-~x
; danx-1
→~-x
, Anda juga dapat bermain golfa-b-1
dana+b+1
.Ini mungkin terlihat seperti tip yang tidak akan sering Anda gunakan, agak seperti menggunakan
~x
bukannya-x-1
tidak sering terjadi, tetapi saya sudah cukup sering menggunakannya untuk melihatnya sebagai tip yang bermanfaat di sini. Terutama dengan pengindeksan array Anda dapat menggunakan ini di atas dalam beberapa kasus.sumber
Kompres atau garis-garis
Trik sederhana yang saya buat ketika mencoba untuk memeras kondisi panjang dirantai oleh ands (atau ors, dalam hal ini hanya mengganti 'semua' dengan 'apa saja').
Misalnya:
Menjadi
sumber
all(array-of-Booleans)
built-in?[a>0,a<10,a+b==4,a+3<1].all?
if 10>a>0 and a+b==4>1>a+3:
Mengandalkan kompiler untuk memberikan kinerja yang diperlukan.
Pastikan untuk mengetahui optimisasi mana yang dijamin oleh kompiler dan pada level optimasi mana, dan gunakan secara bebas. Dan bahkan jika kinerja bukan persyaratan
perhatian, Anda masih dapat menguji dengan optimisasi, dan kemudian hanya mendiskon satu karakter karena kode Anda secara teknis masih valid tanpa flag compiler.Pertimbangkan fungsi Haskell berikut untuk menghitung 2 ^ n (mengabaikan fakta bahwa Haskell sudah memiliki satu atau tiga operator eksponensial bawaan) (23 karakter):
Masalahnya - sangat lambat, berjalan dalam waktu yang eksponensial. Ini mungkin membuat kode Anda tidak dapat diuji atau untuk gagal kendala kinerja yang diberikan oleh pertanyaan. Anda mungkin tergoda untuk menggunakan variabel sementara atau fungsi literal yang segera dipanggil untuk menghindari panggilan fungsi berulang (25 karakter):
Tetapi kompiler sudah dapat melakukan itu untuk Anda, Anda hanya perlu menetapkan
-O
sebagai flag kompiler! Alih-alih menghabiskan beberapa karakter tambahan per situs untuk menghilangkan sub-ekspresi umum secara manual, katakan saja kepada kompiler untuk melakukan optimasi dasar bagi Anda untuk total satu atau dua karakter di seluruh program.sumber
p(x-1)*2
?Mungkin agak jelas tapi ...
Manfaatkan nilai pengembalian operator
Perlu diingat bahwa operator penugasan mengembalikan nilai!
Misalnya, jika Anda ingin menambahkan y ke x dan kemudian memeriksa apakah x lebih besar dari sesuatu, Anda bisa melakukannya
dari pada
Atau mungkin Anda ingin menemukan panjang string setelah memangkasnya:
Daripada
sumber
a = (b=c)+1;
setb
kec
, dan kemudian seta
keb+1
.a=1+b=c
. Dan Anda dapat menambahkan PHP dan JavaScript ke daftar Anda.=
operator prioritas lebih tinggi di sebelah kiri daripada di sebelah kanan, sehingga1+x=2
berlaku dan dievaluasi menjadi3
Memanfaatkan versi bahasa / kompiler / kebiasaan lingkungan / fitur baru
Ini sangat berguna untuk polyglot , tetapi dapat diterapkan untuk tantangan lain. Kadang-kadang, bug penyusun dapat memangkas byte, bug implementasi dapat memungkinkan Anda untuk menyimpan beberapa karakter, atau fitur yang benar-benar canggih dapat meningkatkan skor Anda.
sumber
Gabungkan banyak / bersarang jika memeriksa menggunakan Dan / Atau bila memungkinkan.
yaitu:
dari pada:
sumber
&
, `|) untuk menghapus lebih banyak karakter.&
bukannya&&
menghilangkan 1 karakter dalam beberapa kasus itu mengacaukan prioritas operator dan Anda harus meletakkan tanda kurung untuk membuatnya bekerja. Gunakan dengan bijak.Temukan cara yang lebih baik untuk menginisialisasi variabel Anda
Beberapa jawaban lain hampir menyebutkan hal ini, tetapi dalam banyak bahasa (diketik dengan ketat?), Lebih pendek untuk diinisialisasi
x
sebagai string kosong seperti:atau
x
sebagai rune kosong (char) seperti:dari
dan
Menggunakan nilai yang sudah ada sebelumnya jelas lebih disukai, tetapi tidak begitu mudah.
sumber