Bazı küçük kod golf ipuçları
Bu ipuçları, ayrılan yanıtlar için biraz fazla küçük olduğundan, bu yanıtı bulduğum veya bulduğum ve diğer ipuçlarında henüz belirtilmeyen çok küçük kodlama ipuçları için kullanacağım:
Bir Dize'nin son karakterini kaldırma:
// I used to do something like this:
s.substring(0,s.length()-1) // 27 bytes
// But this is shorter:
s.replaceAll(".$","") // 21 bytes
Bazı durumlarda, son karakterin ne olduğunu önceden biliyorsunuz ve bu karakterin de yalnızca bir kez String içerisinde gerçekleştiğini biliyorsunuz. Bu durumda .splitonun yerine kullanabilirsiniz :
// As example: "100%" to "100"
s.split("%")[0] // 15 bytes
Kodlama kısayolları:
// 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
Tüm kodlamaları kullanılan bir kurallı isme sahip java.nioAPI yanı sıra kullanılan kurallı ad java.iove java.langAPI'ler. İşte Java'da desteklenen tüm kodlamaların tam listesi. Bu yüzden daima ikisinin en kısa olanını kullanın; ikincisi genellikle daha kısadır ( UTF-8vs utf8, Windows-1252vs vs Cp1252gibi), ancak her zaman ( UTF-16BEvs UnicodeBigUnmarked) değil.
Rastgele boolean:
// 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
Asal sayılar:
Asal sayıları denetlemenin veya tüm asal sayıları almanın birçok farklı yolu vardır, ancak @ SaraJ'ın buradaki cevabı en kısa yoldur . İşte referans olarak kopyala-yapıştır:
// 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*/;}}
NOT: Genellikle, nasıl kullanmak istediğinize bağlı olarak mevcut diğer döngülerle birleştirebilirsiniz, böylece ayrı bir yönteme ihtiyaç duymazsınız. Bu , örneğin bu cevapta çok fazla bayt kurtardı .
Math.floor / Math.ceil yerine tamsayı kısaltması:
Eğer kullanıyorsanız pozitif çiftlerde / yüzen ve istediğiniz flooronlardan, kullanmayan Math.floorancak kullanmak (int)(Java tamsayılar üzerinde keser beri) yerine -Cast:
double d = 54.99;
int n=(int)Math.floor(d); // 25 bytes
int m=(int)d; // 13 bytes
// Outputs 54 for both
Aynı numara, yerine yapmak istediğiniz negatif çiftlere / floatlara da uygulanabilir ceil:
double d = -54.99;
int n=(int)Math.ceil(d); // 24 bytes
int m=(int)d; // 13 bytes
// Outputs -54 for both
Parantezden kurtulmak &1yerine kullanın %2:
Çünkü Operatör Önceliği ait &gibi varsayılan aritmetik operatörler daha düşüktür */+-ve %, bazı durumlarda parantez kurtulmuş oluruz.
// So instead of this:
(i+j)%2 // 7 bytes
// Use this:
i+j&1 // 5 bytes
Bunun gerçekten boolean çeklerde yardımcı olmadığına dikkat edin, çünkü o zaman hala paranteze ihtiyacınız olacak, biraz hareket ettirildiler:
(i+j)%2<1 // 9 bytes
(i+j&1)<1 // 9 bytes
BigIntegers ve statik yöntem çağrıları için değişkenler oluşturma:
BigIntegers kullanırken, yalnızca bir kez oluşturun, ardından tekrar kullanabilirsiniz. Bildiğiniz gibi, BigInteger ZERO, ONEve için statik alanlar içeriyor TEN. Yani sadece bu üçünü kullandığınızda, bir ihtiyacınız yok importama java.Math.BigIntegerdoğrudan kullanabilirsiniz .
// 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
NOT: kullanmak zorunda =nullböylece tkullanmak için başlatılır t..
Bazen, baytları kurtarmak üzere başka bir tane oluşturmak için birden fazla BigInteger ekleyebilirsiniz. Diyelim ki 1,10,12bir sebepten dolayı BigIntegers'a sahip olmak istediğinizi varsayalım :
// 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
Yorumlarda doğru bir şekilde belirtildiği gibi, BigInteger t=null;statik yöntem çağrıları için verilen numara başka sınıflarla da kullanılabilir.
Örneğin, 2011'den itibaren bu cevap golf oynayabilir:
// 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() onun yerine toCharArray()
Bir String karakterleri üzerinde döngü oluşturmak istediğinizde, genellikle şunu yaparsınız:
for(char c:s.toCharArray()) // 27 bytes
// or this:
for(String c:s.split("")) // 25 bytes
Karakterler üzerinde gezinmek, yazdırırken veya bunları bir Dizeye eklerken veya benzer bir şeyde kullanışlıdır.
Bununla birlikte, eğer karakterleri sadece bazı unicode-sayı hesaplamaları için kullanırsanız, charile değiştirebilir ve intAND toCharArray()ile değiştirebilirsiniz getBytes():
for(int c:s.getBytes()) // 23 bytes
Veya Java 8+ sürümünde daha da kısa:
s.chars().forEach(c->...) // 22 bytes
Java 10 + 'da yazdırılacak karakterin üzerine gelinmesi artık 22 byte de yapılabilir:
for(var c:s.split("")) // 22 bytes
A'dan itibaren rastgele öğe 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
Bir Dize'nin baştaki / sondaki boşlukları olup olmadığını kontrol edin
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
Neden !=dize açıkken Java'daki değer yerine referans olup olmadığına bakılıyor? Çünkü String#trim" Öndeki ve izleyen beyaz boşluk kaldırılmış olan bu dizenin bir kopyası ya da baştaki veya izleyen beyaz boşluk yoksa bu dizenin bir kopyası " döndürecektir . Bu cevabı birileri bana önerdikten sonra kullandım .
palindrom:
Bir String'in bir palindrom olup olmadığını kontrol etmek için (Dizelerin hem düz hem de tuhaf uzunluklarını göz önünde bulundurarak), en kısa olan budur ( .containsburada çalışır, çünkü hem Dizenin kendisinin hem de ters formunun eşit uzunlukta olduğunu biliriz):
String s=...;
s.contains(new StringBuffer(s).reverse()) // 41 bytes
.contains(...)@assylias 'ın buradaki yorumuna.equals(...+"") teşekkür etmek yerine .
Ya 0, ya da her ikisi de 0?
Ben çoğu zaten düşünüyorum bunu biliyorum: Ya olmadığını kontrol etmek istiyorsanız aveya bsıfırdır, bayt kaydetmek yerine çarpma:
a==0|b==0 // 9 bytes
a*b==0 // 6 bytes
Ve hem olmadığını kontrol etmek istiyorsanız ave bsıfır, bir cinsindendir ya da kullanabilir, ya da her zaman pozitif ise birbirine ekleyin:
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)
Çift = 1, tek = -1; ya da tam tersi
// 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
Bunu eklemek nedeni gördükten sonra oldu k+(k%2<1?1:-1)yılında bu cevap :
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
nTam Programda döngü süreleri
Tam bir programın zorunlu olduğu bir sorunla karşılaşırsak ve belirli bir süreyi tekrarlamamız gerekiyorsa, aşağıdakileri yapabiliriz:
// 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
Aynısı bu aralığı girdi olarak almamız gerektiğinde de geçerlidir:
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
Kredi için @JackAmmo bu yorumda .
dönerken ve ne zaman kullanılacağına try-catch yerine (istisna e) try-finally
Bir kullanamazsınız throws Exceptionama catchgeri dönmeden önce onunla bir şeyler yapmak zorundaysanız, finallyonun yerine kullanabilirsiniz :
try{...}catch(Exception e){return ...;} // 33 bytes
try{...}finally{return ...;} // 22 bytes
Ne zaman ne zaman kullanılacağına dair bir örnek olarak try-catch, benim bu cevabına başvurabilirim (dolaylı golfün kredisi @KamilDrakari'ye gider ). Bu mücadelede NxM matrisinin üzerinden çapraz olarak döngü yapmalıyız, bu yüzden sütunların veya satırların miktarının for-loop'ta maksimum değerimizden daha düşük olup olmadığını belirlememiz gerekir (bayt cinsinden oldukça pahalı i<Math.min(a.length,a[0].length)) :. Yani, sadece alıcı ArrayIndexOutOfBoundsExceptionkullanarak catch-finallybu çeki kısadır ve böylece bayt kaydeder:
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
Not: Bu sadece return r;sonunda sonuçta çalıştı . @KamilDrakari'nin baytları kurtarmak için C # cevabında yaptığı gibi ilk hücreyi değiştirmem önerildi . Ancak, Java’da bunu değiştirmem gerekecek m->{try{for(int i=1;;m[0][0]=f(m[0][0],m[i][i++]));}catch(Exception e){}}(73 bayt), eğer kullansaydım azalan yerine bayt sayısını arttıracağım finally.
Math.pow (2, n)
2 güç istediğinizde, biraz akıllıca bir yaklaşım çok daha kısadır:
(int)Math.pow(2,n) // 16 bytes
(1<<n) // 6 bytes
Parantez kullanmak yerine bit ve mantıksal kontrollerin birleştirilmesi
Ben o artık iyi bilinen düşünüyorum &ve |yerine kullanılabilecek &&ve ||Java (boolean) mantıksal kontrollerde. Bazı durumlarda yine de hataları önlemek için kullanmak &&yerine yine de kullanmak &istersiniz index >= 0 && array[index].doSomething. Eğer burada &&değiştirilirse &, dizideki dizini kullandığı kısmı değerlendirecek ve bu durumda bunun yerine bir ArrayIndexOutOfBoundsExceptionkullanımına neden &&olacaktır &.
Şimdiye kadar &&/ ||vs &/ |in Java temelleri .
Kontrol etmek istediğinizde (A or B) and C, en kestirme işlem böyle bit-operatörleri kullanıyor gibi görünebilir:
(A|B)&C // 7 bytes
Ancak, bit bilge operatörleri , mantıksal kontroller üzerinde operatör önceliğine sahip olduğundan, burada bir bayt kaydetmek için her ikisini de birleştirebilirsiniz:
A|B&&C // 6 bytes
Yerine n+=...-nkullanın(long)...
Bir lambdada hem içinde hem de çıktıda uzun bir süreye sahip olduğunuzda, örneğin kullanırken Math.pow, n+=...-nyerine bir bayt kaydedebilirsiniz (long)....
Örneğin:
n->(long)Math.pow(10,n) // 23 bytes
n->n+=Math.pow(10,n)-n // 22 bytes
Bu bir byte kaydedilen benim bu cevap ve birleştirerek daha iki bayt -n-1için +~nde benim bu cevap .
packageatlanabilir.