Kiat untuk bermain golf di <semua bahasa>

81

Tujuan dari posting ini adalah untuk mengumpulkan semua tips golf yang dapat dengan mudah diterapkan <all languages>daripada yang khusus.

Hanya posting jawaban yang logikanya dapat diterapkan ke sebagian besar bahasa

Tolong, satu tip per jawaban

ajax333221
sumber
5
"Mayoritas" dengan metrik apa?
Berhenti menghidupkan counterclockwis
2
@leftaroundabout dengan metrik kata yang sama
ajax333221
8
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();

Setelah:

for (i=0; i<a+b; i++) i<a?foo():bar();
ugoren
sumber
ugoren loop masih tidak sama. @ Gaffi benar.
kaoD
5
@ 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).

Joey
sumber
12
+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.

Adrian McCarthy
sumber
4
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

if A and not B:
    foo()

sama dengan:

if A>B:
    foo()
Wrzlprmft
sumber
3
Saya tidak pernah memikirkan itu.
cjfaure
27
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).

ugoren
sumber
4
di C Anda dapat menggunakan argc dari main sebagai 1. lihat: codegolf.stackexchange.com/questions/1034/reinvent-the-for-loop/…
std''OrgnlDave
1
@ 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:

(x+1)*(y-1)     ==>    -~x*~-y
Lynn
sumber
30

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 :

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.

#!ruby -an
i=$F.map &:to_i
puts"#{i.reduce &:+} #{i.reduce &:*}"

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.

kernigh
sumber
1
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
Jaket
sumber
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.

ratchet freak
sumber
8
26 untuk bahasa non-case-sensitive. :-)
Gaffi
12
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 .

if(a>b){r=a;}else{r=b;}

dapat ditulis sebagai

r=a>b?a:b;
TuanZander
sumber
25
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.

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.

Laikoni
sumber
23

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

Sean Latham
sumber
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

Tobia
sumber
15
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.

Jadi, 7 10 == 00000111 2 , 15 10 == 00001111 2 , 31 10 == 00011111 2 dan seterusnya.

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.

Sean Latham
sumber
18

Gunakan kembali parameter fungsi, bukan variabel baru

Grifon
sumber
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)
masterX244
18

Lebih besar / kurang dari untuk menyimpan digit:

//use:
if(n>9){A}else{B}
//instead of:
if(n<10){B}else{A}

Hanya ingat untuk menukar kode dari ifke elsedan 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)

ajax333221
sumber
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

if(x>24&&x<51)

Lebih pendek 2 byte daripada menggunakan

if(x>=25&&x<=50)
Jojodmo
sumber
3
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;
}
Gaffi
sumber
5
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

Titus
sumber
12

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

["Foo""Bar""Baz""Quux"]  # 23 chars

menjadi

"Foo
Bar
Baz
Quux"n/  # 20 chars

Untuk beberapa bahasa, ambangnya serendah satu string. Misal di Jawa,

new String[]{"Foo"}  // 19 chars

menjadi

"Foo".split("~")  // 16 chars
Peter Taylor
sumber
6
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.

anatolyg
sumber
10

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:

  • 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)
Titus
sumber
7

Lebih pendek untuk-loop

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

for(blah;blah;blah 2,...,blah X)blah 1;

dan simpan 3 byte

Kritixi Lithos
sumber
@ETHproductions Terima kasih telah bermain golf :)
Kritixi Lithos
Dan jika itu foradalah pernyataan terakhir, itu ;menjadi opsional
elipszilon
7

Gunakan unary ~untuk a-b-1dana+b+1

Selain saran @ Lynn tentang x+1-~x; dan x-1~-x , Anda juga dapat bermain golf a-b-1dan a+b+1.

a-b-1    // 5 bytes
a+~b     // 4 bytes

a+b+1    // 5 bytes
a-~b     // 4 bytes

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.

Kevin Cruijssen
sumber
6

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:

if a>0 and a<10 and a+b==4 and a+3<1:

Menjadi

if all([a>0,a<10,a+b==4,a+3<1]):
LemonBoy
sumber
Itu yang keren, saya harus mencobanya!
stokastic
4
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.

John Dvorak
sumber
@ EETProduk ya, maaf, saya lakukan
John Dvorak
Bukankah seharusnya contoh pertama saja p(x-1)*2?
Cyoce
5

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

if(25<x+=y)

dari pada

x+=y;if(x>25)

Atau mungkin Anda ingin menemukan panjang string setelah memangkasnya:

strlen(s=trim(s))

Daripada

s=trim(s);strlen(s)
orp
sumber
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 , 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.

programmer5000
sumber
4

Gabungkan banyak / bersarang jika memeriksa menggunakan Dan / Atau bila memungkinkan.

yaitu:

if (a && (b || c)) {

}

dari pada:

if (a) {
    if (b) {
        //Do Stuff
    } elseif (c) {
        //Do same stuff
    }
}
Gaffi
sumber
5
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.

kucing
sumber