Apa tips umum yang Anda miliki untuk bermain golf di C ++? Saya mencari ide yang dapat diterapkan pada masalah kode golf secara umum yang setidaknya agak spesifik untuk C ++ (mis. "Hapus komentar" bukan jawaban). Silakan kirim satu tip per jawaban.
48
Jawaban:
Operator kondisional terner
?:
sering dapat digunakan sebagai berdiri di untuk sederhanaif
-else
pernyataan di tabungan yang cukup.Ini bernilai khusus karena dapat digunakan untuk memilih nilai alternatif seperti pada
sumber
e
dano
. Perhatikan bahwa ini berbeda dari cara operator ini bekerja di c di mana trik ini tidak berfungsi karena tidak dapat menjadi nilai.std::endl
dengan'\n'
yang menghemat 5 karakterKadang-kadang Anda dapat menyimpan dua karakter dengan menggunakan fakta bahwa variabel durasi penyimpanan statis (yang terutama mencakup semua variabel lingkup global) secara otomatis nol diinisialisasi pada awal (tidak seperti variabel otomatis di mana Anda tidak memiliki jaminan seperti itu). Jadi, bukannya
kamu bisa menulis
sumber
Beberapa kompiler (misalnya GCC) mendukung konstanta multi-karakter . Ini dapat menyimpan beberapa karakter ketika nilai integer besar diperlukan. Contoh:
Nilainya spesifik implementasi. Biasanya nilai
'ab'
is256*'a'+'b'
atau'a'+256*'b'
. Anda dapat menentukan hingga 4 karakter di antara tanda kutip.sumber
Salah satu yang saya temukan berguna:
Mengambil keuntungan dari kenyataan bahwa nilai-nilai non-nol dievaluasi
true
dalam ekspresi boolean, dan yangx&&y
mengevaluasix*y
ketika berhadapan dengan booleanmengevaluasi ke
Anda hanya harus mewaspadai luapan, seperti yang ditunjukkan di bawah ini.
sumber
x!=0 && y!=0
. Tetapi ketika menggunakan perkalian, Anda harus berhati-hati dengan luapan. Saat menggunakan bilangan bulat 32-bit x = y = 65536 (dan beberapa kombinasi kekuatan keduanya) juga akan menghasilkan x * y = 0 .&&
memiliki perilaku hubung singkat yang*
kurang. Misalnya, Anda tidak dapat menggantii++!=0&&j++!=0
dengani++*j++
.Gunakan tipe berikut:
Untuk kata / jenis yang berulang, gunakan
#defines
:Ini hanya layak jika Anda menggunakan
while
banyak untuk mengganti 10 karakter tambahan. ( Tentang 4. )sumber
Jika Anda ingin menggunakan C ++ 0x, Anda dapat menggunakan fitur-fitur baru seperti lambdas .
sumber
Jika memungkinkan, ubah
&&
dan||
ke&
dan|
masing - masing.Saat menggunakan pernyataan if sederhana:
dapat diubah menjadi:
yang menyimpan karakter.
sumber
Alih-alih menggunakan
while(1)
, menggunakanfor(;;)
, menyimpan satu karakter :)sumber
Menggunakan operator koma sebagai pengganti kurung buka dan tutup dapat menyimpan beberapa karakter, jika Anda memiliki situasi di mana klausa Anda memiliki lebih dari satu pernyataan di dalamnya:
vs.
Dua karakter disimpan pada IF biasa, atau tiga total untuk IF / ELSE.
Sebagai titik perbedaan antara C dan C ++, hasil dari ekspresi koma dalam C ++ secara keseluruhan dapat digunakan sebagai nilai lv ... FWIW.
sumber
Karena elemen array disimpan secara langsung setelah satu sama lain dalam memori, bukannya sesuatu seperti ini:
Anda dapat melakukan sesuatu seperti ini:
Jelas tidak satu pun di atas golf, untuk keterbacaan, tetapi secara eksplisit menggunakan pointer dapat menghemat banyak ruang.
sumber
for(int* i=array; i<array+25*25; i++)
? Maka Anda hanya perlu melacak satu variabel.Cukup jelas, tetapi Anda menggunakan banyak perpustakaan standar,
using namespace std;
mungkin menyimpan beberapa karakter.sumber
using std::name;
mungkin lebih pendek.std::
lima kali atau lebih.Yang perlu diingat adalah
a[i]
sama dengan*(a+i)
.Ganti
a[0]
dengan*a
untuk penghematan dua karakter. Juga,a[i][0]
sama dengan*a[i]
dana[0][i]
menyusut kei[*a]
. Jadi jika Anda meng-coding0
indeks dalam array Anda, cara yang lebih baik mungkin ada.sumber
Alih-alih menulis kekuatan besar 10, gunakan notasi . Misalnya,
a=1000000000
lebih panjang daria=1e9
. Ini dapat diperluas ke nomor lain sepertia=1e9+24
lebih baik daripadaa=1000000024
.sumber
1e9/x
tidak sama dengan1000000000/x
atauint(1e9)/x
.Anda dapat menggunakan operator ternary
?:
tanpa ekspresi di blok-benar (ini menghemat satu byte)Lihat di sini
sumber
Header lebih pendek
Ini khusus GCC, mungkin dapat diperluas ke kompiler lain.
Header yang dikompilasi.
Dalam G ++
bits/stdc++.h
adalah header yang dikompilasi terdiri dari semua header lainnya. Jika Anda perluimport
2 yang berbeda, Anda bisa menggunakan ini.Header lebih pendek.
Ini semua tajuk yang terdaftar di http://en.cppreference.com/w/cpp/header :
Tampilkan cuplikan kode
diurutkan dalam peningkatan urutan panjang.
Beberapa dari mereka sudah lebih lama dari
bits/stdc++.h
, dan beberapa dari mereka memerlukan dukungan C ++ 17. Beberapa lainnya tidak didukung oleh TIO G ++ (untuk alasan yang saya tidak tahu). Saring mereka yang kita miliki:Tampilkan cuplikan kode
Mungkin saja beberapa dari mereka dapat diganti dengan yang lebih pendek. Hanya pencarian biner apakah yang Anda butuhkan dapat diganti. Khususnya:
sumber
#import
bukannya#include
memberi Anda satu byte lagi.Selain itu, karakter spasi antara
#import
dan tajuk belum tentu:Dan jika Anda membutuhkan sesuatu dari
stdlib
tajuk, Anda dapat mengimpor tajuk apa pun dengan wadah STL (lebih disukaiset
ataumap
) sebagai gantinyacstdlib
.sumber
Operasi aritmatika di Boolean:
Meskipun
lebih baik dari
itu tidak sebagus
Juga, menggunakan #define pada apa pun yang sering digunakan. Seringkali lebih pendek daripada menggunakan fungsi, karena nama jenis tidak diperlukan.
Gabungkan hal-hal sebanyak mungkin:
sama dengan
sumber
x
sebagai nilai danx++
sebagai nilai. poin perilaku dan urutan yang tidak ditentukanGunakan lambda generik sebagai templat murah
Untuk tipe selain
int
, menggunakannya sebagai argumen fungsi bisa jadi mahal. Namun, lambda generik diperkenalkan (dalam C ++ 14?) Dan memungkinkan lambda menjadi templat - menggunakanauto
untuk tipe argumen dapat menghemat byte. Membandingkan:Lambda Generik juga sangat nyaman untuk menerima iterator - mungkin cara terbaik untuk menerima input array di C ++ adalah
[](auto a, auto z)
, di manaa
danz
dilewatkan sebagaibegin()
danend()
dari array / vektor / daftar / dll.sumber
Dalam upaya pertama saya di kode golf untuk tugas "Kurangi angka berikutnya" Saya sudah mulai dari fungsi (58 byte)
kemudian amankan 5 byte dengan menggeser ke lambda dan memindahkan inisialisasi dari
for
(53)dan akhirnya setelah beralih dari
for
kewhile
saya mendapat 51 byte:Kode tes yang tidak disatukan adalah seperti:
MEMPERBARUI:
Sebenarnya
for
bisa mencapai panjang yang sama denganwhile
:sumber
Agak terlambat ke pesta, kurasa ...
Jika Anda ingin mengubah ekspresi menjadi -1 dan 1 alih-alih 0 dan 1, alih-alih ini:
melakukan hal ini:
Ini dapat menghemat beberapa byte tergantung pada penggunaan.
sumber
int x=(a*10>5)*2-1;
, tidak bisakah Anda melakukannyaint x=a*10>5?1:-1;
, yang lebih pendek 1 byte?Jika Anda ingin menukar dua variabel integer a dan b,
dapat digunakan, menyimpan 5 karakter dari cara standar
sumber
,t
di ints dibuat sebelumnya dan kemudiant=a;a=b;b=t;
sudah lebih pendek 3 byte daria+=b;b=a-b;a-=b;
. Namun, Andaa^=b^=a^=b;
bahkan lebih pendek dari itu, jadi +1 dari saya. Saya tidak tahu C ++, tapi itu memang berfungsi . Sebagai pegolf kode Java saya sedih sepertinya tidak bekerja di sana . :(a^=b;b^=a;a^=b;
bekerja dengan baik di java.a^=b;b^=a;a^=b;
memang berfungsi, tetapi lebih panjang dari,t
+t=a;a=b;b=t;
. Maaf karena menyebut Java, karena di luar topik di sini. Tapi tip yang bagus untuk C ++ codegolfers!Gunakan GCC bawaan daripada mengimpor
Jika Anda menggunakan kompiler GCC, terkadang membantu menggunakan fungsi bawaannya, seperti
__builtin_puts
atau__builtin_clz
. Sebagai contoh,44 byte:
50 byte:
sumber
Jika Anda menggunakan C ++ 11 atau lebih baru (yang seharusnya selalu menjadi masalah sekarang), gunakan
auto
untuk tipe yang kompleks, jika memungkinkan.Contoh: 54 Bytes, bukan 66
Juga, karena kinerja tidak masalah, untuk beberapa tantangan,
std::list
mungkin hanya melakukan pekerjaan untuk beberapa byte lebih sedikit:sumber
Fungsi dalam
<algorithm>
sering membutuhkan passinga.begin(),a.end()
yang benar-benar panjang, bukannya Anda dapat menggunakan&a[0],&*end(a)
untuk menyimpan 3 byte jikaa
inivector
ataustring
.sumber
Jangan gunakan
string("")
, gunakan""
. Menghemat 8 byte.sumber
"" + 'a'
adalahchar* + char
, yang selain pointer, sedangkanstd::string("") + 'a'
adalahstd::string + char
- string concatenation.string()
akan bekerja.