Kiat untuk bermain golf di Jawa

86

Apakah ada jalan pintas berguna yang bisa digunakan di Jawa?

Seperti yang ditunjukkan di bawah ini, importsudah menambahkan setidaknya 17 karakter ke program.

import java.io.*;

Saya mengerti bahwa solusi sederhana adalah dengan menggunakan bahasa lain, tetapi tampaknya menjadi tantangan nyata untuk mempersingkat program Java.


Tip harus spesifik untuk Java: jika mereka berlaku untuk sebagian besar bahasa sejenis C, mereka termasuk dalam daftar tips yang lebih umum .

rampok
sumber
9
packagebisa dilewati.
st0le
Dalam jawaban, tidak bisakah saya mengabaikan impor dengan asumsi mereka ada di sana?
Fabricio
1
@Fabricio Tidak kecuali OP menentukannya.
nyuszika7h
32
Kiat terbaik tentang golf Java: jangan gunakan itu. ;)
kirbyfan64sos
4
"Saya ingin bermain golf di java" semoga berhasil
sagiksp

Jawaban:

85
  • Gunakan java terbaru yang mungkin. Java 8 memungkinkan Anda menggunakan ekspresi lambda, jadi gunakan itu jika Anda memerlukan sesuatu bahkan seperti objek fungsional.

  • Tentukan fungsi singkat untuk hal-hal yang sering Anda gunakan. Misalnya, Anda memiliki seratus panggilan untuk exampleClassInstance.doSomething(someParameter), menetapkan fungsi baru void d(ParameterType p){exampleClassInstance.doSomething(p)}dan menggunakannya untuk menghemat beberapa karakter.

  • Jika Anda menggunakan nama kelas panjang tertentu lebih dari sekali, seperti

    MyEventHandlerProxyQueueExecutorServiceCollectionAccessManagerFactory

    sebagai gantinya tentukan kelas baru:

    class X extends MyEventHandlerProxyQueueExecutorServiceCollectionAccessManagerFactory{}

    Jika Anda hanya menggunakan satu metode tertentu dari kelas itu (tetapi masih perlu membuat instance), Anda dapat menentukan versi singkat di dalam kelas baru pada saat yang sama.

  • Gunakan parameter tipe fungsi untuk mempersingkat hal-hal, jika memungkinkan, seperti ini:

    <T>void p(T o){System.out.println(o);}
  • Gunakan for(;;)sebagai ganti while(true).

  • Jangan gunakan pengubah akses kecuali benar-benar diperlukan.

  • Jangan gunakan finaluntuk apa pun.

  • Jangan pernah meletakkan blok setelah forloop (tapi loop foreach for(x:y)berbeda). Pernyataan tambahan harus ditempatkan di dalam forpernyataan itu sendiri, seperti for(int i=0;i<m;a(i),b(++i))c(i);.

  • Gunakan penugasan sebaris, peningkatan, instantiasi. Gunakan kelas inline anonim jika perlu. Gunakan lambdas sebagai gantinya jika memungkinkan. Panggilan fungsi sarang. Beberapa fungsi dijamin mengembalikan objek induknya, yang ini sebenarnya bahkan dimaksudkan untuk dirantai bersama.

  • mainMetode Anda throws Exception, bukan menangkap mereka.

  • Errorlebih pendek dari Exception. Jika karena alasan tertentu Anda benar - benar perlu throwmengirim pesan ke tumpukan, gunakan Error, meskipun situasinya normal.

  • Jika suatu kondisi membutuhkan penghentian segera, gunakan int a=1/0;daripada throw null;atau System.exit(0);. Pada waktu berjalan, ini melempar ArithmeticException. Jika Anda sudah memiliki variabel numerik dalam kode Anda, gunakan saja. (Jika sudah import static java.lang.System.*;, pergilah exit(0);.)

  • Alih-alih mengimplementasikan antarmuka, seperti List<E>, memperpanjang segera (atau tidak-begitu-langsung, jika ada keuntungan untuk melakukannya sama sekali) kelas anak, seperti AbstractList<E>, yang menyediakan implementasi standar dari sebagian besar metode, dan hanya membutuhkan implementasi dari beberapa potong kunci.

  • Tuliskan kode Anda terlebih dahulu, dengan baris baru, lekukan, dan nama variabel lengkap. Setelah Anda memiliki kode yang berfungsi, Anda dapat mempersingkat nama, memindahkan deklarasi, dan menambahkan metode pintasan. Dengan menulisnya panjang untuk memulai, Anda memberi diri Anda lebih banyak kesempatan untuk menyederhanakan program secara keseluruhan.

  • Bandingkan optimalisasi alternatif dengan sepotong kode, karena strategi paling optimal dapat berubah secara dramatis dengan perubahan yang sangat kecil pada kode. Misalnya:

    • Jika Anda hanya memiliki hingga dua panggilan Arrays.sort(a), cara paling efisien adalah dengan memanggilnya dengan nama lengkap yang memenuhi syarat java.util.Arrays.sort(a),.
    • Dengan tiga panggilan atau lebih, lebih efisien daripada menambahkan metode pintas void s(int[]a){java.util.Arrays.sort(a);}. Ini harus tetap menggunakan nama yang sepenuhnya memenuhi syarat dalam kasus ini. (Jika Anda membutuhkan lebih dari satu kelebihan, Anda mungkin salah melakukannya.)
    • Namun, jika kode Anda juga perlu menyalin array di beberapa titik (biasanya dilakukan dengan forloop pendek dalam bermain golf, dengan tidak adanya metode perpustakaan yang mudah diakses), Anda dapat memanfaatkan Arrays.copyOfuntuk melakukan tugas tersebut. Ketika lebih dari satu metode digunakan, dan ada 3 panggilan atau lebih, melakukan import static java.util.Arrays.*;adalah cara paling efisien untuk merujuk pada metode-metode tersebut. Setelah itu, hanya jika Anda memiliki lebih dari 8 panggilan terpisah yang sortharus Anda gunakan metode pintas untuk itu, dan hanya di 5 atau lebih panggilan adalah jalan pintas dijamin untuk copyOf.

    Satu-satunya cara nyata untuk melakukan analisis pada kode adalah untuk benar-benar melakukan modifikasi potensial pada salinan kode, dan kemudian membandingkan hasilnya.

  • Hindari menggunakan someTypeValue.toString();metode, sebagai gantinya hanya menambahkan someTypeValue+"".

  • Jika Anda memang membutuhkan windows, jangan gunakan Swing, gunakan AWT (kecuali Anda benar-benar membutuhkan sesuatu dari Swing). Bandingkan import javax.swing.*;dan import java.awt.*;. Selain itu, komponen di Swing telah menjadi Jditambahkan ke nama mereka ( JFrame, JLabel, dll), tetapi komponen dalam AWT tidak ( Frame, Label, dll)

AJMansfield
sumber
43

Gunakan interfacesebagai ganti class.

Di java 8, metode statis ditambahkan ke antarmuka. Dalam antarmuka, semua metode bersifat publik secara default. Karena itu

class A{public static void main(String[]a){}}

sekarang dapat disingkat menjadi

interface A{static void main(String[]a){}}

yang jelas lebih pendek.

Misalnya, saya menggunakan fitur ini di Hello, World! tantangan.

TheNumberOne
sumber
8
Saya tidak tahu itu! +1, trik bagus
HyperNeutrino
Yay, kurang matang!
CalculatorFeline
3
Saya harus sebagian tidak setuju (juga, saya mengalahkan Anda dalam tantangan "Halo, Dunia!", Menggunakan teknik itu).
Olivier Grégoire
37

Dengan varargs Anda dapat "melemparkan" parameter ke array dengan tipe yang sama:

void f(String...x){
    x=x[0].split("someregex");
    // some code using the array
}

dari pada

void f(String s){
    String[]x=s.split("someregex");
    // some code using the array
}
masterX244
sumber
31

Dengan impor statis :

import static java.lang.System.out;
// even shorter (thanks to Johannes Kuhn):
import static java.lang.System.*;

Anda dapat menghemat beberapa pelat boiler nanti, tetapi Anda perlu beberapa pemanggilan untuk mencapai hasil:

public static void main (String[] args) {
    out.println ("foo");    
    out.println ("bar");    
    out.println ("baz");    
}
Pengguna tidak diketahui
sumber
8
:HAI. Kamu bisa melakukan ini?! Dan selama ini saya berpikir bahwa ini tidak mungkin Java!
Justin
12
Anda bahkan dapat menggunakan import static java.lang.System.*.
Johannes Kuhn
1
Saya tahu ini adalah jawaban lama, tetapi di Jawa 10 sekarang Anda dapat melakukan var o=System.out;yang hanya perlu digunakan dua kali sebelum terbayar
Luke Stevens
@LukeStevens: Ya, mungkin Anda menemukan beberapa perbaikan lain, mungkin dengan Java10, dan membentuk jawaban terpisah di sekitar Java10?
pengguna tidak diketahui
1
@LukeStevens Akan var o=System.out.printlnberhasil?
MilkyWay90
25

Argumen untuk maintidak harus dipanggil args, dan Anda dapat memotong beberapa spasi putih:

public static void main(String[]a){}

akan baik-baik saja.

daniero
sumber
1
Apakah jawaban perlu menyertakan fungsi utama jika tidak secara eksplisit menyatakan untuk menulis program lengkap? Saya telah menggunakan ekspresi lambda sebagai jawaban.
Makotosan
3
@Makotosan Tidak, mereka tidak; Lambdas biasanya baik-baik saja.
daniero
21

Jika Anda harus menggunakan ekspresi boolean trueatau false, ganti dengan 1>0dan 1<0masing - masing.

Sebagai contoh:

boolean found=false;
for(i=0; i<10; i++) if(a[i]==42) found=true;

Contoh pencarian linear ini dapat dikurangi menjadi

boolean f=1<0;
for(i=0;i<10;)if(a[i++]==42)f=1>0;
ace_HongKongIndependence
sumber
11
Jika Anda akan membutuhkan banyak true/false, cukup tambahkan boolean t=1>0,f=1<0;. Maka alih-alih 1>0, gunakan tdan simpan dua karakter per penggunaan. Payoff lebih 1>0metode datang pada 10 kegunaan.
Geobits
24
@ Geobits: boolean t=1>0,f=!t;- satu char lebih pendek!
bobbel
6
Contohnya tidak terlalu bagus. Dalam hal ini dan banyak (!) Lainnya yang dapat Anda hindari menggunakan true/ falsesecara langsung: f|=a[i++]==42;menyimpan cukup banyak.
Ingo Bürk
@ IngoBürk Benar. Ketika saya menulis ini, saya lebih banyak memikirkan fungsi-fungsi perpustakaan yang digunakan boolean, tetapi karena saya tidak dapat menemukan contoh apa pun pada saat penulisan ini (saya biasanya tidak kode di Jawa) saya hanya menulis contoh sederhana.
ace_HongKongIndependence
1
@ Geobits tidak terlalu akrab dengan java tetapi bisakah Anda mendefinisikan 1 dan menggunakan t dan! T (lagi saya tidak tahu Java, hanya ingin tahu)
Albert Renshaw
20

Jika Anda akan sering menggunakan beberapa metode, tetapkan kelas residennya ke sebuah variabel. Misalnya, tetapkan System.outke variabel:

java.io.PrintStream o=System.out;
//now I can call o.print() or o.println() to the same effect as System.out.println()

Juga untuk Integer.parseInt():

Integer i=1;
i.parseInt("some string");

Ini hampir pasti akan memicu ide peringatan tentang "mengakses metode statis dari variabel"

Justin
sumber
((Integer)1).parseInt("1")bekerja juga.
Magic Gurita Guci
5
@cococuting new Integer("1")bahkan lebih pendek. Tetapi yang dimaksud Justin dengan jawabannya adalah bahwa Anda dapat menggunakan kembali variabel yang sudah Anda miliki untuk panggilan statis. Seperti yang saya jelaskan di bagian bawah jawaban ini.
Kevin Cruijssen
19

Daripada menggunakan import static java.lang.System.*teknik untuk menghemat println()pernyataan, saya menemukan bahwa mendefinisikan metode berikut ini jauh lebih efektif untuk menyimpan karakter:

static<T>void p(T p){
    System.out.println(p);
}

Ini karena dapat dipanggil sebagai p(myString)daripada out.println(myString)yang memiliki hasil karakter yang jauh lebih cepat dan lebih dramatis.

asteri
sumber
19

Ini mungkin tampak jelas, tetapi ada opsi yang lebih pendek untuk beberapa Mathfungsi:

a=Math.max(b,c);
a=b>c?b:c;

a=Math.min(b,c);
a=b<c?b:c;

a=Math.abs(b);
a=b<0?-b:b;

a=Math.round(b);
a=(int)(b+.5);          // watch for precision loss if it matters
Geobit
sumber
14

Jika Anda perlu Integer.MAX_VALUE(2147483647), gunakan -1>>>1. Integer.MIN_VALUE(-2147483648) lebih baik ditulis 1<<31.

dfeuer
sumber
14

Jika Anda perlu mengambil nomor dari argumen (atau string lain), biasanya Anda melihat sesuatu seperti:

public static void main(String[]a){
    int n=Integer.valueOf(a[0]);
    ...
}

Banyak kali, Anda tidak perlu sebuah Integer. Banyak tantangan tidak menggunakan jumlah besar. Karena Shortdan Byteakan sama-sama menghapus kotak ke int, gunakan yang lebih tepat valueOf()dan simpan beberapa byte.

Jaga variabel aktual Anda sebagai int, karena lebih pendek dari keduanya bytedan short:

int n=Byte.valueOf(a[0]);

Jika Anda perlu melakukan ini untuk beberapa angka, Anda dapat menggabungkan dengan metode ini :

Byte b=1;
int n=b.valueOf(a[0]),m=b.valueOf(a[1])...
Geobit
sumber
9
int n=new Byte(a[0]);tiga lebih pendek. Jika jumlahnya mungkin lebih besar, gunakan long n=new Long(a[0]), itu masih lebih baik daripada intdalam kebanyakan kasus.
Ypnypn
14

Jangan gunakan public class. Metode utama harus publik, tetapi kelasnya tidak. Kode ini berfungsi:

class S{public static void main(String[]a){System.out.println("works");}}

Anda dapat menjalankan java Smeskipun class Sbukan kelas publik. ( Pembaruan: Saya menggunakan Java 7 ketika saya menulis tip ini. Di Java 8, metode utama Anda harus di antarmuka . Di Java 5 atau 6, metode utama Anda harus dalam enum .)

Banyak programmer Java tidak tahu ini! Sekitar setengah jawaban untuk pertanyaan Stack Overflow tentang utama di kelas non-publik dengan keliru mengklaim bahwa metode utama harus di kelas publik. Sekarang kamu tahu lebih baik. Hapus publicin public classdan simpan 7 karakter.

kernigh
sumber
1
Kecuali jika Anda menargetkan Java sebelum 1,8, konstruknya interface s{static void main(String[]...lebih pendek. Jika Anda harus memiliki file sumber yang dapat dikompilasi dan metode utama. Karena dalam antarmuka Java 1.8, semua metode bersifat publik sehingga Anda dapat melewati pengubah pada metode.
Douglas Diadakan
Saya belum lama menggunakan Java, jadi jawaban saya sudah usang. Saya lupa bahwa antarmuka dapat memiliki metode di Java 8.
kernigh
Saya tidak mempelajarinya dari pemrograman; Saya mempelajarinya dari bermain golf :)
Douglas Held
14

Beberapa tips kode-golf kecil

Kiat-kiat ini agak terlalu kecil untuk jawaban yang terpisah, jadi saya akan menggunakan jawaban ini untuk kiat kodegolf yang sangat kecil yang saya temukan atau hasilkan, dan belum disebutkan dalam kiat lain:

Menghapus karakter terakhir dari String:

// I used to do something like this:
s.substring(0,s.length()-1)     // 27 bytes

// But this is shorter:
s.replaceAll(".$","")           // 21 bytes

Dalam beberapa kasus Anda tahu apa karakter terakhir sebelumnya, dan Anda juga tahu karakter ini hanya muncul sekali di String. Dalam hal ini Anda dapat menggunakan .splitsebagai gantinya:

// As example: "100%" to "100"
s.split("%")[0]                 // 15 bytes

Pintasan penyandian:

// When you want to get the UTF-8 bytes I used to do this:
s.getBytes("UTF-8");     // 20 bytes

// But you can also use "UTF8" for the same result:
s.getBytes("UTF8");      // 19 bytes

Semua penyandian memiliki nama kanonik yang digunakan dalam java.nioAPI, serta nama kanonik yang digunakan dalam API java.iodan java.lang. Berikut adalah daftar lengkap semua penyandian yang didukung di Jawa. Jadi selalu gunakan yang terpendek dari keduanya; yang kedua biasanya lebih pendek (seperti UTF-8vs utf8, Windows-1252vs Cp1252, dll), tetapi tidak selalu ( UTF-16BEvs UnicodeBigUnmarked).

Boolean acak:

// You could do something like this:
new java.util.Random().nextBoolean()     // 36 bytes

// But as mentioned before in @Geobits' answer, Math.random() doesn't require an import:
Math.random()<.5                         // 16 bytes

Bilangan prima:

Ada banyak cara berbeda untuk memeriksa bilangan prima atau mendapatkan semua bilangan prima, tetapi jawaban @ SaraJ di sini adalah yang terpendek. Berikut ini adalah copy-paste sebagai referensi:

// Check if n is a prime:
n->{int i=1;for(;n%++i%n>0;);return n==i;}

// Which can easily be modified to loop through primes:
v->{for(int n=2,i;;){for(i=1;n%++i%n>0;);if(n++==i)/*do something with prime `i` here*/;}}

CATATAN: Biasanya Anda dapat menggabungkannya dengan loop lain yang ada tergantung pada bagaimana Anda ingin menggunakannya, sehingga Anda tidak perlu metode terpisah. Ini menyimpan banyak byte dalam jawaban ini misalnya.

Pemotongan bilangan alih-alih Math.floor / Math.ceil:

Jika Anda menggunakan doubl / float positif dan Anda menginginkannya floor, jangan gunakan Math.floortetapi gunakan (int)-cast sebagai gantinya (karena Java memotong bilangan bulat):

double d = 54.99;

int n=(int)Math.floor(d);     // 25 bytes

int m=(int)d;                 // 13 bytes

// Outputs 54 for both

Trik yang sama dapat diterapkan pada dobel / mengapung negatif yang Anda inginkan ceil:

double d = -54.99;

int n=(int)Math.ceil(d);     // 24 bytes

int m=(int)d;                // 13 bytes

// Outputs -54 for both

Gunakan &1alih-alih %2untuk menyingkirkan tanda kurung:

Karena Operator Precedence dari &lebih rendah dari operator aritmatika standar seperti */+-dan %, Anda dapat menyingkirkan kurung dalam beberapa kasus.

// So instead of this:
(i+j)%2     // 7 bytes

// Use this:
i+j&1       // 5 bytes

Perhatikan bahwa ini tidak benar-benar membantu dalam pemeriksaan boolean, karena Anda masih membutuhkan tanda kurung, mereka hanya bergerak sedikit:

(i+j)%2<1    // 9 bytes
(i+j&1)<1    // 9 bytes

BigIntegers dan membuat variabel untuk panggilan metode statis:

Saat menggunakan BigIntegers, buat hanya sekali yang kemudian dapat Anda gunakan kembali. Seperti yang Anda ketahui, BigInteger berisi bidang statis untuk ZERO, ONEdan TEN. Jadi saat Anda hanya menggunakan ketiganya, Anda tidak perlu importtetapi bisa menggunakannya java.Math.BigIntegersecara langsung.

// So instead of this:
import java.math.BigInteger.*;
BigInteger a=BigInteger.ONE,b=BigInteger.ZERO;                // 76 bytes

// or this:
java.math.BigInteger a=java.math.BigInteger.ONE,b=a.ZERO;     // 57 bytes

// Use this:
java.math.BigInteger t=null,a=t.ONE,b=t.ZERO;                 // 45 bytes                  

CATATAN: Anda harus menggunakan =nullbegitu tdiinisialisasi untuk menggunakan t..

Terkadang Anda dapat menambahkan beberapa BigIntegers untuk membuat yang lain untuk menyimpan byte. Jadi katakanlah Anda ingin memiliki BigIntegers 1,10,12karena beberapa alasan:

// So instead of this:
BigInteger t=null,a=t.ONE,b=t.TEN,c=new BigInteger(12);     // 55 bytes

// Use this:
BigInteger t=null,a=t.ONE,b=t.TEN,c=b.add(a).add(a);        // 52 bytes

Seperti yang ditunjukkan dengan benar dalam komentar, trik dengan BigInteger t=null;untuk panggilan metode statis juga dapat digunakan dengan kelas lain.
Misalnya, jawaban dari 2011 ini dapat di-golf:

// 173 bytes:
import java.util.*;class g{public static void main(String[]p){String[]a=p[0].split(""),b=p[1].split("");Arrays.sort(a);Arrays.sort(b);System.out.print(Arrays.equals(a,b));}}

// 163 bytes
class g{public static void main(String[]p){java.util.Arrays x=null;String[]a=p[0].split(""),b=p[1].split("");x.sort(a);x.sort(b);System.out.print(x.equals(a,b));}}

getBytes() dari pada toCharArray()

Saat Anda ingin mengulang karakter String, biasanya Anda akan melakukan ini:

for(char c:s.toCharArray())    // 27 bytes
// or this:
for(String c:s.split(""))      // 25 bytes

Melonggarkan karakter dapat berguna saat mencetaknya, atau menambahkannya ke String, atau yang serupa.

Namun, jika Anda hanya menggunakan karakter untuk beberapa perhitungan angka unikode, Anda bisa mengganti chardengan int, DAN Anda bisa mengganti toCharArray()dengan getBytes():

for(int c:s.getBytes())        // 23 bytes

Atau bahkan lebih pendek di Java 8+:

s.chars().forEach(c->...)      // 22 bytes

Di Java 10+ pengulangan karakter untuk dicetak sekarang juga dapat dilakukan dalam 22 byte:

for(var c:s.split(""))         // 22 bytes

Item acak dari List:

List l=...;

// When we have an `import java.util.*;` in our code, shuffling is shortest:
return l.get(new Random().nextInt(l.size()));     // 45 bytes
return l.get((int)(Math.random()*l.size()));      // 44 bytes
Collections.shuffle(l);return l.get(0);           // 39 bytes

// When we don't have an `import java.util.*` in our code, `Math.random` is shortest:
return l.get(new java.util.Random().nextInt(l.size()));     // 55 bytes
return l.get((int)(Math.random()*l.size()));                // 44 bytes
java.util.Collections.shuffle(l);return l.get(0);           // 49 bytes

Periksa apakah sebuah String berisi spasi awal / akhir

String s=...;

// I used to use a regex like this:
s.matches(" .*|.* ")     // 20 bytes
// But this is shorter:
!s.trim().equals(s)      // 19 bytes
// And this is even shorter due to a nice feature of String#trim:
s!=s.trim()              // 11 bytes

Mengapa ini bekerja, ketika !=di Strings adalah untuk memeriksa referensi alih-alih nilai di Jawa? Karena String#trimakan mengembalikan " Salinan string ini dengan spasi putih awal dan akhir dihapus, atau string ini jika tidak memiliki spasi putih awal atau akhir . " Saya telah menggunakan ini, setelah seseorang menyarankan ini kepada saya, dalam jawaban saya ini .

Palindrome:

Untuk memeriksa apakah suatu String adalah palindrome (dengan mengingat panjang Strings yang genap dan ganjil), ini adalah yang terpendek ( .containsbekerja di sini karena kita tahu baik String itu sendiri maupun bentuknya yang dibalik memiliki panjang yang sama):

String s=...;
s.contains(new StringBuffer(s).reverse())    // 41 bytes

.contains(...)alih-alih .equals(...+"")terima kasih atas komentar @assylias di sini .

Entah 0, atau keduanya 0?

Saya pikir sebagian besar sudah tahu yang ini: jika Anda ingin memeriksa apakah salah aatau bnol, gandakan untuk menyimpan byte:

a==0|b==0    // 9 bytes
a*b==0       // 6 bytes

Dan jika Anda ingin memeriksa apakah keduanya adan bnol, Anda bisa menggunakan bitwise-OR, atau menambahkannya bersama jika keduanya selalu positif:

a==0&b==0    // 9 bytes
(a|b)==0     // 8 bytes (if either `a`, `b` or both can be negative)
a+b<1        // 5 bytes (this only works if neither `a` nor `b` can be negative)

Even = 1, odd = -1; atau sebaliknya

// even = 1; odd = -1:
n%2<1?1:-1        // 10 bytes
1-n%2*2           // 7 bytes

// even = -1; odd = 1:
n%2<1?-1:1        // 10 bytes
n%2*2-1           // 7 bytes

Alasan saya menambahkan ini setelah melihat k+(k%2<1?1:-1)di jawaban ini :

k+(k%2<1?1:-1)    // 14 bytes

// This would already have been shorter:
k%2<1?k+1:k-1     // 13 bytes

// But it can also be:
k%2*-2-~k         // 9 bytes

Loop nkali dalam Program Lengkap

Jika kita memiliki tantangan di mana program lengkap wajib, dan kita perlu mengulang sejumlah waktu tertentu, kita dapat melakukan hal berikut:

// instead of:
interface M{static void main(String[]a){for(int n=50;n-->0;)/*do something*/}}  // 78 bytes
// we could do:
interface M{static void main(String[]a){for(M m:new M[50])/*do something*/}}    // 76 bytes

Hal yang sama berlaku ketika kita harus mengambil rentang ini sebagai input:

interface M{static void main(String[]a){for(int n=new Byte(a[0]);n-->0;)/*do something*/}}  // 90 bytes
interface M{static void main(String[]a){for(M m:new M[new Byte(a[0])])/*do something*/}}    // 88 bytes

Kredit ke @JackAmmo dalam komentar ini .

try-akhirnya alih-alih try-catch (Exception e) saat kembali, dan kapan menggunakannya

Jika Anda tidak dapat menggunakan throws Exceptiontetapi harus catchdan melakukan sesuatu dengannya sebelum kembali, Anda dapat menggunakan finally:

try{...}catch(Exception e){return ...;}    // 33 bytes
try{...}finally{return ...;}               // 22 bytes

Adapun contoh kapan harus menggunakan try-catch, saya bisa merujuk ke jawaban saya ini (kredit untuk golf tidak langsung masuk ke @KamilDrakari ). Dalam tantangan ini kita harus mengulang secara diagonal pada matriks NxM, jadi kita harus menentukan apakah jumlah kolom atau jumlah baris adalah yang terendah sebagai maksimum kita dalam for-loop (yang cukup mahal dalam hal byte:) i<Math.min(a.length,a[0].length). Jadi, hanya menangkap ArrayIndexOutOfBoundsExceptionpenggunaan catch-finallylebih pendek dari pemeriksaan ini, dan dengan demikian menghemat byte:

int[] a = ...;

int r=0,i=0;for(;i<Math.min(a.length,a[0].length);)r=...i++...;return r;    // 66 bytes

int r=0,i=0;try{for(;;)r=...i++...;}finally{return r;}                      // 48 bytes

CATATAN: Ini hanya berhasil karena return r;pada akhirnya. Saya disarankan untuk memodifikasi sel pertama, seperti yang dilakukan @KamilDrakari dalam jawaban C # untuk menyimpan byte. Namun, di Jawa ini berarti saya harus mengubahnya ke m->{try{for(int i=1;;m[0][0]=f(m[0][0],m[i][i++]));}catch(Exception e){}}(73 byte), sebenarnya meningkatkan jumlah byte bukannya menurun jika saya bisa menggunakan finally.

Math.pow (2, n)

Saat Anda menginginkan kekuatan 2, pendekatan sedikit lebih bijaksana:

(int)Math.pow(2,n)    // 16 bytes
(1<<n)                // 6 bytes

Menggabungkan pemeriksaan bit-bijaksana dan logis alih-alih menggunakan tanda kurung

Saya pikir ini sudah terkenal sekarang &dan |dapat digunakan sebagai pengganti &&dan ||dalam Java (boolean) pemeriksaan logis. Dalam beberapa kasus, Anda tetap ingin menggunakan &&alih-alih &mencegah kesalahan, misalnya index >= 0 && array[index].doSomething. Jika &&akan diubah ke &sini, ia masih akan mengevaluasi bagian di mana ia menggunakan indeks dalam array, menyebabkan ArrayIndexOutOfBoundsException, maka penggunaan &&dalam kasus ini bukan &.

Sejauh ini dasar-dasar &&/ ||vs &/ |di Jawa.

Saat Anda ingin memeriksa (A or B) and C, yang terpendek mungkin menggunakan operator bit-bijaksana seperti ini:

(A|B)&C    // 7 bytes

Namun, karena operator bit-wise memiliki prioritas operator atas pemeriksaan logis, Anda dapat menggabungkan keduanya untuk menyimpan byte di sini:

A|B&&C     // 6 bytes

Gunakan n+=...-nsebagai ganti(long)...

Ketika Anda memiliki panjang masuk dan keluaran dalam lambda, misalnya saat menggunakan Math.pow, Anda dapat menyimpan byte dengan menggunakan n+=...-nalih-alih (long)....
Sebagai contoh:

n->(long)Math.pow(10,n)    // 23 bytes
n->n+=Math.pow(10,n)-n     // 22 bytes

Ini menyimpan satu byte dalam jawaban saya ini , dan bahkan dua byte dengan menggabungkan -n-1ke +~ndalam jawaban saya ini .

Kevin Cruijssen
sumber
Lebih umum untuk poin terakhir Anda, Anda dapat mengakses / meminta anggota statis dari konteks non-statis seperti turunan objek.
Poke
1
Saya tidak mengerti tip langit-langit Anda. Mengapa kamu ingin langit-langit positive integers? Juga, saya tidak yakin apakah implementasi ceil bekerja .
Jonathan Frech
1
since Java automatically floors on integers; Saya pikir istilah yang tepat adalah pemotongan , bukan lantai .
Jonathan Frech
1
Strategi Palindrome lainString t="";for(int i=s.length();--i>=0;t+=s.charAt(i));return s.equals(t);
Roberto Graham
1
@RobertoGraham Saya sebenarnya menyalin kode asli saya dari tantangan yang salah .. Cukup s.equals(new StringBuffer(s).reverse()+"")sudah.
Kevin Cruijssen
11

Untuk bermain golf yang tidak memerlukan input, Anda dapat menggunakan blok statis, dan menjalankannya dengan baik tanpa metode utama, cukup kompilasi dengan Java 6.

public class StaticExample{
    static {
        //do stuff
    }
}
Hebat
sumber
1
Apakah Anda mencoba mengkompilasi dan menjalankannya? Blok ini dijalankan ketika kelas dimuat oleh kelas loader. Tetapi pemuat kelas tidak akan memuat apa pun sampai ia mengetahui kelas dengan metode utama.
Cruncher
@Cruncher Anda dapat menyiasatinya sendiri dengan mengatakan javapada baris perintah / dalam file manifes kelas mana yang akan dimuat.
AJMansfield
6
@Cruncher, ini bekerja dengan Java 6. Java 7 mengubah cara kerjanya.
Peter Taylor
1
Melempar pengecualian di akhir tetapi berhasil! Bahkan di Jawa 7
stommestack
2
@JopVernooij Jika Anda tidak ingin ada pengecualian yang dilemparkan ke wajah Anda, Anda dapat system.exit (), tetapi Anda akan membuang karakter, tidak ada tantangan golf yang pernah meminta Anda untuk menghindari pengecualian;)
Fabinout
11

Kita semua tahu tentang bitor xor ( ^), tetapi juga xor logis.

Jadi (a||b)&&!(a&&b)sederhananya a^b.

Sekarang kita bisa menggunakan xor.

Selain itu , operator |dan& juga berfungsi , hanya ingat bahwa prioritas operator berubah.

Justin
sumber
5
Selama Anda ingat prioritas, Anda bisa menggunakan & dan |juga. Mungkin bermanfaat jika kondisi Anda sudah dalam tanda kurung, atau jika Anda sudah bekerja dengan boolean.
Geobits
1
Jika Anda memerlukan (jauh) prioritas lebih rendah, Anda dapat menggunakan !=sebagai ganti ^untuk xor, dan ==untuk
xnor
11

Anda tidak harus menggunakan Character.toLowerCase(char c). Sebaliknya gunakan (c|32). Alih-alih Character.toUpperCase(char c)digunakan (c&~32). Ini hanya berfungsi dengan huruf ASCII.

TheNumberOne
sumber
c|~32akan cenderung menghasilkan -1 ... lebih baik digunakan c-32.
feersum
5
@feersum Itu tidak akan berfungsi jika Anda ingin membuat huruf besar huruf besar.
TheNumberOne
11

Konversi String ke angka

Ada beberapa cara untuk mengonversi String ke nilai numerik:

String s = "12";

ABC.parseABC :

Short.parseShort(s); // 20 bytes
Integer.parseInt(s); // 20 bytes
Long.parseLong(s);   // 18 bytes

ABC.nilai :

Short.valueOf(s);    // 17 bytes
Integer.valueOf(s);  // 19 bytes
Long.valueOf(s);     // 16 bytes

ABC.decode :

// Note: does not work for numeric values with leading zeros,
// since these will be converted to octal numbers instead
Short.decode(s);     // 16 bytes
Integer.decode(s);   // 18 bytes
Long.decode(s);      // 15 bytes

ABC baru :

new Short(s);        // 13 bytes
new Integer(s);      // 15 bytes
new Long(s);         // 12 bytes

Jadi, untuk bermain golf, lebih baik menggunakan konstruktor saat mengonversi String ke nilai numerik.

Hal yang sama berlaku untuk Double; Float; dan Byte.


Ini tidak selalu berlaku ketika Anda dapat menggunakan kembali primitif yang sudah ada sebagai objek.
Sebagai contoh, katakanlah kita memiliki kode berikut:

// NOTE: Pretty bad example, because changing the short to int would probably be shorter..
//       but it's just an example to get the point across

short f(short i,String s){
  short r=new Short(s);  // 21 bytes
  ... // Do something with both shorts
}

Anda dapat menggunakan .decodealih-alih konstruktor yang lebih pendek dengan menggunakan kembali parameter sebagai objek:

short f(Short i,String s){   // Note the short parameter has changed to Short here
  short r=i.decode(s);   // 20 bytes
  ... // Do something with both shorts
}
Kevin Cruijssen
sumber
10

Jangan gunakan Random!

Secara umum, jika Anda memerlukan angka acak, Randomadalah cara yang mengerikan untuk melakukannya *. Jauh lebih baik untuk digunakan Math.random(). Untuk menggunakannya Random, Anda perlu melakukan ini (misalkan kita membutuhkan int):

import java.util.*;
Random r=new Random();
a=r.nextInt(9);
b=r.nextInt(9);

Bandingkan dengan:

a=(int)(Math.random()*9);
b=(int)(Math.random()*9);

dan:

int r(int m){return(int)(Math.random()*m);}
a=r(9);
b=r(9);

Metode pertama mengambil 41+15nkarakter ( njumlah panggilan). Yang kedua adalah 25nkarakter, dan yang ketiga adalah 43+7n.

Jadi, jika Anda hanya membutuhkannya sekali atau dua kali, gunakan Math.random()metode sebaris . Untuk tiga panggilan atau lebih, Anda akan menghemat dengan menggunakan suatu fungsi. Salah satu menyimpan karakter pada penggunaan pertama berakhir Random.


Jika Anda sudah menggunakan Math.random()untuk double, ingat bahwa pada empat penggunaan, itu masih penghematan untuk menariknya ke:

double r(){return Math.random();}

Untuk 33 karakter, Anda akan menghemat 10 pada setiap panggilan r()


Memperbarui

Jika Anda membutuhkan integer dan ingin menghemat casting, jangan melemparkannya! Java auto-casts jika Anda melakukan operasi alih-alih tugas. Membandingkan:

a=(int)(Math.random()*9);
a=9;a*=Math.random();

* Kecuali Anda harus menyemai PRNG untuk hasil yang dapat diprediksi. Kemudian, saya tidak melihat banyak jalan di sekitarnya.

Geobit
sumber
2
Jangan lupa tentang itu Random#nextGaussian.
Justin
@ Quincunx Benar, melakukan matematika untuk mendapatkan distribusi normal yang baik akan kehilangan Anda setiap penghematan yang Anda dapatkan. Saya hanya akan menyebutnya sebagai pengecualian yang membuktikan aturan;)
Geobits
Catatan yang (int)(Math.random()*9)memiliki bias modulo sangat kecil, karena Math.random()mengembalikan 2 53 nilai yang mungkin, dan 2 53 bukan kelipatan 9. Probabilitas setiap angka berada di 1/9 plus atau minus 5 / (9 * 2 ** 53), kesalahan sangat kecil, hampir persis 1/9.
kernigh
@Kernigh Benar, saya menggunakan 9hanya sebagai contoh, bisa apa saja. Saya relatif yakin bahwa nextInt()(atau Randommetode lain ) memiliki bias kecil juga, hanya karena cara kerja PRNG Java.
Geobits
1
Sesuatu terkait ketika Anda menginginkan boolean acak: alih-alih new java.util.Random().nextBoolean()Anda dapat menggunakannya Math.random()<.5.
Kevin Cruijssen
7

Saya tidak tahu apakah Anda akan mempertimbangkan Java 'murni' ini, tetapi Memproses memungkinkan Anda membuat program dengan sedikit pengaturan awal (selesai secara otomatis).

Untuk output konsol, Anda dapat memiliki sesuatu yang sederhana seperti:

println("hi"); //done

untuk output grafis, lebih sedikit:

void setup() {
  size(640,480);
}
void draw() {
  fill(255,0,0); //color used to fill shapes
  rect(50,50,25,25); //25x25 pixel square at x=50,y=50
}
Nuh
sumber
1
+1 Sumber daya luar biasa! Saya pasti akan bermain-main dengannya.
Rob
Apakah tidak apa-apa jika saya menambahkan jawaban orang lain untuk yang ini? Atau apakah itu mengalahkan tujuan wiki komunitas?
Rob
2
Omong-omong, Anda bahkan tidak perlu menelepon sizesama sekali; standarnya adalah 100 x 100 piksel persegi. Di sebagian besar OS, bingkai di sekitarnya akan sekitar dua kali lebih besar, dengan kotak di tengah dan seluruh area diisi dengan konten yang diambil dari desktop.
AJMansfield
1
Untuk output grafis, jika Anda tidak memerlukan animasi, Anda bisa menulis semuanya di luar setup()dan draw()menggunakan "mode statis". Anda juga dapat menggunakan warna hex 6-digit dan penerjemah akan mengubahnya, yang kadang-kadang terbayar ( #FF8000< 255,128,0), dan jika Anda menggunakan skala abu-abu, hanya satu nomor yang perlu ditentukan ( 255< 255,255,255)
quat
7

Memendekkan kembali

Anda dapat mempersingkat pernyataan string yang dikembalikan oleh byte dengan:

return "something";

untuk

return"something";

Dan, jika Anda memulai pernyataan pengembalian dengan tanda kurung, Anda dapat melakukan hal yang sama dengan mereka:

return (1+taxRate)*value;

untuk

return(1+taxRate)*value;

Saya kira kutipan dianggap seperti tanda kurung? Saya benar-benar mengambil ini melalui AppleScript, cukup lucu, dan berpikir mungkin layak disebutkan.

Addison Crump
sumber
1
Hal yang sama berlaku untuk tanda-tanda angka, seperti return-n;bukan return -n;atau return~n;bukan return ~n;. Serta tunggal bukan tanda kutip ganda:return'A';
Kevin Cruijssen
1
Pada dasarnya, bekerja untuk apa pun yang tidak dapat menjadi bagian dari pengidentifikasi (yaitu non-huruf dan non-digit).
Paŭlo Ebermann
7

Jangan takut menggunakan notasi ilmiah

Jika Anda berurusan dengan ganda, atau mengapung, Anda dapat menggunakan notasi ilmiah untuk angka. Jadi, alih-alih menulis, double a=1000Anda dapat mengubahnya double a=1e3untuk menghemat 1 byte.

pengguna902383
sumber
7

Coba gunakan int sebagai gantiboolean

Dalam beberapa kasus saya telah menemukan bahwa lebih pendek untuk mengembalikan nilai integer dari metode yang biasanya mengembalikan boolean, mirip dengan apa yang mungkin dilakukan dalam program C.

Langsung dari kelelawar intadalah 4 byte lebih pendek dari boolean. Setiap kali Anda menulis return 0alih-alih return 1<0, Anda menyimpan tambahan 2 byte dan sama untuk return 1 overreturn 1>0 .

Jebakan di sini adalah bahwa setiap kali Anda ingin menggunakan nilai kembali secara langsung sebagai boolean, harganya 2 byte ( if(p(n))v. if(p(n)>0)). Ini dapat dibuat dengan menggunakan aritmatika boolean. Diberi skenario yang dibuat-buat di mana Anda ingin menulis

void a(int[]t){t[0]+=p(n)?10:0;}

Anda malah bisa menulis

void a(int[]t){t[0]+=p(n)*10;}

untuk menghemat 2 byte.

ankh-morpork
sumber
6
Saya sering melakukan ini ketika bermain golf, tetapi perlu diingat bahwa konsensus umum adalah bahwa 0dan 1tidak merupakan salah / benar di Jawa (dan JLS tidak menganggapnya demikian). Jadi, jika golf secara khusus meminta kebenaran / kepalsuan, Anda perlu membukanya (dan, sayangnya, membuatnya booleanberfungsi, melemparkan lebih banyak byte padanya).
Geobits
2
t[0]+=p(n):10?0;Apakah ini valid?
dorukayhan
@dorukayhan tidak, itu memang dimaksudkan t[0]+=p(n)?10:0;. (Saya mengeditnya.)
Paŭlo Ebermann
6

Jika Anda menggunakan enum alih-alih kelas , Anda menyimpan satu karakter.

enum NoClass {
    F, G, H;    
    public static void main (String[] args) {

    }
}

Tetapi Anda harus memperkenalkan setidaknya satu contoh enum (F, G, H dalam contoh ini) yang harus membayar sendiri.

Pengguna tidak diketahui
sumber
2
Sepertinya Anda tidak memerlukan instance enum. Saya lakukan enum M{;public static void main(String[]a){...}tanpa masalah.
Danny
3
@ Danny Tapi kemudian itu tidak menyimpan karakter apa pun. class M{panjangnya persis sama dengan enum M{;. Dalam hal ini, saya akan memilih classkarena lebih cantik (IMO)
Justin
1
setidaknya bagiku enum{bekerja tanpa ;after; itu hanya IDE yang mengeluh bahwa ada kesalahan tetapi kompiler menerimanya
masterX244
@ masterX244 Kompiler / versi apa? Milik saya membuat ulah dan tidak akan melakukannya.
Geobits
bekerja di java 1.7 untuk saya (muncul s, ned untuk menyelidiki penyebab lebih lanjut dengan pembaruan ke .8 berhenti bekerja)
masterX244
5

Ketika Anda memiliki metode yang harus mengembalikan booleanatau Boolean, yaitu:

// Return true if the (non-negative) input is dividable by 5
boolean c(int i){return i%5<1;}

Anda dapat mengubah boolean/ Booleankembali-jenis Objectuntuk menyimpan 1 byte:

Object c(int i){return i%5<1;}

Selain itu, seperti yang mungkin telah Anda perhatikan, Anda dapat menggunakan tanda <1centang alih-alih ==0menyimpan satu byte. Meskipun itu lebih merupakan tip kode-golf umum daripada Java-spesifik.
Ini sebagian besar digunakan ketika bilangan bulat tidak boleh negatif, seperti memeriksa panjang:

a.length<1

dari pada

a.length==0
Kevin Cruijssen
sumber
1
Tip yang bagus! Anda mungkin ingin menambahkan contoh lain di bagian "jika tidak boleh negatif" untuk menggambarkannya, karena c(-21)kembali truedengan yang saat ini.
Geobits
Diklarifikasi Juga, bukankah maksud Anda, c(-20)bukan -21? -21 % 5 = 4dan -20 % 5 = 0.
Kevin Cruijssen
1
Tidak, maksudku -21. -21 % 5 != 4di Jawa, yang merupakan poin saya. Fungsi dibagi oleh lima akan bekerja dengan benar jika modulus selalu mengembalikan non-negatif, tetapi tidak. Lihat cuplikan contoh ini .
Geobits
@ Geobits Ah, terima kasih untuk contohnya. Saya hampir tidak pernah menggunakan angka negatif %, jadi saya lupa Java mengembalikan sisanya daripada modulus, maka bedanya ..
Kevin Cruijssen
5

Bagaimana Draw di Java ...

Ini adalah pelat GUI cat terpendek yang mungkin:

import java.awt.*;
static void main(String[]x){
    new Frame(){
        public void paint(Graphics g){
            // Draw your stuff here.
        }    
    }.show();
}

Golf untuk 111 Bytes:

import java.awt.*;static void main(String[]x){new Frame(){public void paint(Graphics g){/*CodeHere*/}}.show();}
Guci Gurita Ajaib
sumber
5

Hindari StringBuilders

Menambah barang ke Stringbyte membutuhkan jauh lebih sedikit.

// s is a StringBuilder
s.append("Hello, World!");

// S is a String
S+="Hello, World!";

Jika Anda harus membalik string dan mencetaknya segera, gunakan a StringBuffer .

System.out.print(new StringBuilder("Hello, World!").reverse());
System.out.print(new StringBuffer("Hello, World!").reverse()); // Note that you can omit toString() when printing a non-String object

Jika Anda harus membalik string dan kemudian melakukan sesuatu selain mencetaknya, gunakan forsetiap loop.

String b=new StringBuffer("Hello, World!").reverse().toString();
String B="";for(String c:"Hello, World!".split(""))B=c+B;
dorukayhan
sumber
3
Loop foreach lebih pendek dari pada StringBufferuntuk membalik string. String b="";for(char c:"Hello, World!".toCharArray()){b=c+b;}
Poke
1
Anda juga harus menghapus {}dari loop foreach jika Anda akan menggunakan metode itu.
Geobits
1
Simpan 2 byte menggunakan String s:"".split("")bukan char c:"".toCharArray().
charlie
Jika Anda java.util.stream.Streamsudah mengimpor, dan jika Anda perlu membuat panggilan lain ke hasil (seperti B.chartAt(42)) atau jika Anda hanya perlu meneruskan hasilnya ke fungsi (seperti f(B)), maka menggunakan for(:)adalah sama dengan Stream.of("Hello, World!".split("")).reduce("",(a,b)->b+a).
charlie
Kedua baris dalam contoh Anda dengan masing-masing dapat di-golf. Yang pertama bisa menjadi: String b=new StringBuffer("Hello, World!").reverse()+"";( .toStringdiganti dengan +""), dan baris kedua Anda bisa menjadi: String B="";for(String c:"Hello, World!".split(""))B=c+B;( charke Stringdan .toCharArray()ke .split("")).
Kevin Cruijssen
5

Gunakan Java 10's var

Jika Anda mendefinisikan satu variabel dari jenis tertentu, gunakan var .

Contohnya

var i=0;                        // int
var l=0L;                       // long
var s="";                       // String
var a=new int[]{1,2,3};         // int[]
var i=java.math.BigInteger.ONE; // BigInteger
var m=new java.util.HashMap();  // HashMap
var i=3+"abc".length()          // int
var a="a b c".split(" ");       // String[]
for(var a:"a b c".split(" "))   // String

Tidak dapat digunakan dalam salah satu contoh berikut

var tidak dapat digunakan dalam banyak contoh

var i=1,j=2;           // only one variable is accepted at a time
var a={1,2,3};         // arrays must be explicitly declared
var f=a->a+" ";        // can't know what type a is.
var f=String::replace; // method references aren't properly implied (weirdly, though)
Olivier Grégoire
sumber
RE mengapa ini tidak bekerja dengan referensi metode, perhatikan bahwa ada antarmuka fungsional standar untuk hanya satu set kecil tanda tangan (dan metode dapat membuang pengecualian yang diperiksa).
Jakob
4

Dalam kebanyakan kasus, program Anda akan single-threaded, yaitu hanya memiliki satu utas berjalan Anda dapat memanfaatkan fakta ini dengan returnmenggunakan metode utama saat Anda harus keluar secara instan.

static void main(String[]a){if(condition)return;}

Bandingkan dengan "benar" mengakhiri program:

static void main(String[]a){if(condition)System.exit(0);}

Atau menunjuk ke null:

static void main(String[]a){if(condition)throw null;}

Atau membaginya dengan 0:

static void main(String[]a){if(condition)int A=1/0;}
dorukayhan
sumber
4

Terkadang, satu pernyataan for-loop mungkin bisa diganti. Pertimbangkan kode berikut:

int m(int x){int i=1;for(;x%++i==0;);return i;}

Ini adalah for-loop sederhana yang merupakan solusi untuk pertanyaan ini .

Karena kita tahu bahwa itidak akan cukup besar untuk menyebabkan kesalahan StackOverflow, sebagai gantinya kita dapat mengganti for-loop dengan rekursi:

int m(int x,int i){return x%++i>0?i:m(x,i);}

Kami dapat mensimulasikan loop dengan menggunakan operator ternary dalam pernyataan kembali untuk menyebabkan rekursi.

Pengurangan ini agak spesifik, tapi saya bisa membayangkan lebih banyak situasi di mana ini akan berguna.

Addison Crump
sumber
4

Menggunakan ... (varags) sebagai parameter

Dalam beberapa kasus lebih pendek untuk menggunakan Java varargs sebagai parameter daripada yang longgar.
Sebagai contoh:

// Example input/output: 5, 4, 3 -> 60000
int calculateVolumeInLiters(int width, int height, int depth){
  return width * height * depth * 1000;
}

Akan golf paling banyak untuk ini:

int c(int w,int h,int d){return w*h*d*1000;} // 44 bytes

Tetapi dapat di-golf byte tambahan untuk ini:

int c(int...a){return a[0]*a[1]*a[2]*1000;}  // 43 bytes

Perhatikan bahwa ketiga bilangan bulat hanya diakses satu kali dalam metode itu sendiri. Karena intcukup pendek, itu hanya menguntungkan jika Anda menggunakannya masing-masing hanya sekali di dalam metode, dan memiliki tiga atau lebih dari mereka sebagai parameter.

Dengan parameter yang lebih panjang ini biasanya lebih bermanfaat. Sebagai contoh, ini adalah jawaban asli saya untuk tantangan ini (menghitung kemunculan karakter input dalam string input):

// Example input/output: tttggloyoi, t -> 3

int c(String a,char b){return a.replaceAll("[^"+b+"]","").length();} // 68 bytes

Dan saya disarankan untuk golf ini:

int c(String a,char b){return a.split(b+"").length-1;}               // 54 bytes

Tapi akhirnya saya bermain golf dengan ini ...:

int c(String...a){return a[0].split(a[1]).length-1;}                 // 52 bytes

CATATAN: Jika pertanyaan / tantangan meminta input yang fleksibel, tentu saja ...dapat disingkat []. Jika pertanyaan / tantangan secara spesifik meminta, katakanlah, tiga Stringinput dan tidak mengizinkan String-array yang mengandung tiga nilai, Anda dapat menggunakan String...sebagai gantinya String a,String b,String c.

Kevin Cruijssen
sumber
2
Tidak bisakah Anda menggunakan String[]daripada menggunakan varargs? (menghemat 1 byte lebih banyak)
Kritixi Lithos
@KritixiLithos Hmm .. bagus. Tapi itu terutama tergantung pada seberapa fleksibel input untuk tantangan. Jika ada format input yang dibolehkan, maka itu akan lebih pendek. Saya akan menambahkan ini ke tips ini, terima kasih.
Kevin Cruijssen