Java'da golf oynamak için ipuçları


86

Java'da kullanılabilecek herhangi bir yararlı kısayol var mı?

Aşağıda gösterildiği gibi, importbir programa zaten en az 17 karakter ekler.

import java.io.*;

Basit bir çözümün başka bir dil kullanmak olacağını biliyorum, ancak Java programlarını kısaltmak için gerçek bir zorluk olduğu görülüyor.


İpuçları Java'ya özel olmalıdır: eğer çoğu C benzeri dile uygulanabilirlerse, daha genel ipuçları listesine aittirler .


9
packageatlanabilir.
st0le

Cevap olarak, orada olduklarını farz ederek ithalatları ihmal edemez miyim?
Fabricio

1
@Fabricio OP belirtmediği sürece hayır.
nyuszika7h

32
Java ile golf hakkında en iyi ipucu: kullanmayın. ;)
kirbyfan64sos

4
"Ben java golf
oynamak

Yanıtlar:


85
  • Mümkün olan en son java'yı kullanın. Java 8, lambda ifadeleri kullanmanıza izin verir, bu nedenle işlevsel nesneler gibi bir şeye ihtiyacınız olursa kullanın .

  • Çok kullandığınız şeyler için kısaltılmış işlevleri tanımlayın. Örneğin, yüzlerce çağrınız var exampleClassInstance.doSomething(someParameter), yeni bir işlev tanımlayın void d(ParameterType p){exampleClassInstance.doSomething(p)}ve kendinize bazı karakterleri kaydetmek için kullanın.

  • Belirli bir uzun sınıf adını bir kereden fazla kullanıyorsanız,

    MyEventHandlerProxyQueueExecutorServiceCollectionAccessManagerFactory

    bunun yerine yeni bir sınıf tanımlayın:

    class X extends MyEventHandlerProxyQueueExecutorServiceCollectionAccessManagerFactory{}

    Eğer o sınıfın sadece belirli bir metodunu kullanıyorsanız (fakat yine de başlatmanız gerekebilir), aynı zamanda yeni sınıfın içinde kısaltılmış bir versiyon tanımlayabilirsiniz.

  • Mümkün oldukça şeyleri kısaltmak için işlev türü parametrelerini kullanın:

    <T>void p(T o){System.out.println(o);}
  • Yerine for(;;)kullanın while(true).

  • Kesinlikle gerekli olmadıkça erişim değiştiricileri kullanmayın.

  • Hiçbir finalşey için kullanmayın .

  • Bir fordöngüden sonra asla bir blok koyma (ancak bir foreach döngüsü for(x:y)farklıdır). forGibi ek ifadenin içine ek ifadeler yerleştirilmelidir for(int i=0;i<m;a(i),b(++i))c(i);.

  • Satır içi atama, artış, örnekleme kullanın. Uygun olan yerlerde anonim satır içi sınıfları kullanın. Mümkünse bunun yerine lambda kullanın. Nest işlevi çağrıları. Bazı işlevler, üst nesneyi döndürmek için garantili, bu olanları aslında bile vardır demek birlikte zincirleme edilecek.

  • Kişisel mainyöntem throws Exceptionler, değil onları yakalar.

  • Errordaha kısa Exception. Herhangi bir nedenle olursa gerçekten gerek throwyığın mesajların kadar bir kullanma Errorderece normal bir durum olsa bile,.

  • Bazı koşulların derhal sonlandırılmasını gerektiriyorsa, veya int a=1/0;yerine kullanın . Çalışma zamanında, bu bir atar . Kodunuzda zaten sayısal bir değişken varsa, bunun yerine kullanın. (Zaten sahipseniz , gidin .)throw null;System.exit(0);ArithmeticExceptionimport static java.lang.System.*;exit(0);

  • Arabirimleri uygulamak yerine, örneğin List<E>, AbstractList<E>yöntemlerin çoğunun varsayılan uygulamalarını sağlayan ve yalnızca uygulama gerektiren birkaç anahtar parça.

  • İlk önce yeni satırlar, girintiler ve tam değişken adlarıyla kodunuzu önce el ile yazınız. Çalışma kodunuz olduğunda, adları kısaltabilir, bildirimleri taşıyabilir ve kısayol yöntemleri ekleyebilirsiniz. Başlamak için uzun yazarak, programı bir bütün olarak basitleştirmek için kendinize daha fazla fırsat verirsiniz.

  • Alternatif optimizasyonları bir kod parçasıyla karşılaştırın, çünkü en uygun strateji koddaki çok küçük değişikliklerle önemli ölçüde değişebilir. Örneğin:

    • Yalnızca iki adede kadar Arrays.sort(a)çağrınız varsa, en etkili yol, tam adı ile çağırmaktır java.util.Arrays.sort(a).
    • Üç veya daha fazla aramada, bir kısayol yöntemi eklemek daha etkilidir void s(int[]a){java.util.Arrays.sort(a);}. Bu, bu durumda hala tam olan adı kullanmalıdır. (Birden fazla aşırı yüke ihtiyacınız varsa, muhtemelen yanlış yapıyorsunuzdur.)
    • Bununla birlikte, kodunuzun bir noktada bir diziyi de kopyalaması gerekiyorsa (genellikle forgolf oynamakta kısa bir döngü ile, kolayca erişilebilir bir kütüphane yönteminin olmadığı durumlarda), Arrays.copyOfgörevi yerine getirme avantajından yararlanabilirsiniz . Birden fazla yöntem kullanıldığında ve 3 veya daha fazla çağrı olduğunda, yapmak import static java.util.Arrays.*;bu yöntemlere başvurmanın en etkili yoludur. Ondan sonra, yalnızca 8'den fazla ayrı çağrınız sortvarsa, bunun için bir kısayol yöntemi kullanıyorsanız ve yalnızca 5 veya daha fazla çağrıda için gereken bir kısayol olur copyOf.

    Kod üzerinde böyle bir analiz yapmanın tek gerçek yolu, kodun kopyalarında potansiyel değişiklikler yapmak ve ardından sonuçları karşılaştırmaktır.

  • someTypeValue.toString();Yöntemi kullanmaktan kaçının , sadece ekleyin someTypeValue+"".

  • Pencerelere ihtiyacınız varsa, Swing kullanmayın, AWT kullanın (gerçekten Swing'den bir şeye ihtiyacınız yoksa). Karşılaştırma import javax.swing.*;ve import java.awt.*;. Ayrıca, Swing bileşenleri var JAdlarının (başına ilave JFrame, JLabelvb), ancak AWT bileşenleri yok ( Frame, Label, vs)


43

Yerine interfacekullanın class.

Java 8'de, arayüzlere statik yöntemler eklendi. Arayüzlerde, tüm yöntemler varsayılan olarak herkese açıktır. sonuç olarak

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

şimdi kısaltılabilir

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

ki belli ki daha kısa.

Örneğin, ben kullanılan bu özelliği Hello, World! meydan okuma.


8
Bunu bilmiyordum! +1, güzel hile
HyperNeutrino

Yay, daha az kazan!
CalculatorFeline

3
Kısmen katılmıyorum (ayrıca, bu tekniği kullanarak "Merhaba, Dünya!" Yarışmasında seni yendim).
Olivier Grégoire

37

Varargs ile aynı tipte bir diziye parametre atayabilirsiniz :

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

onun yerine

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

31

Bir ile statik ithalat :

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

Daha sonra bazı kazanları kurtarabilirsin, ancak bir kazancı elde etmek için birden fazla çağrıya ihtiyacın var:

public static void main (String[] args) {
    out.println ("foo");    
    out.println ("bar");    
    out.println ("baz");    
}

8
:Ö. Bunu yapabilirsiniz?! Ve bunca zaman bunun imkansız olduğunu düşündüm Java!
Justin,

12
hatta kullanabilirsiniz import static java.lang.System.*.
Johannes Kuhn

1
Bunun eski bir cevap olduğunu biliyorum, ancak Java 10'da artık var o=System.out;ödeme yapmadan önce iki kez kullanılması gereken işleri yapabilirsiniz
Luke Stevens

@LukeStevens: Pekala, belki de Java10 ile mümkün olan başka geliştirmeler bulup Java10 etrafında ayrı bir cevap oluşturabilirsiniz?
kullanıcı bilinmeyen

1
@LukeStevens Çalışır var o=System.out.printlnmı?
MilkyWay90

25

Argümanının mainçağrılması gerekmez argsve bazı boşlukları azaltabilirsiniz:

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

sadece iyi yapacağım.


1
Tam bir program yazmayı açıkça belirtmiyorsa, cevapların ana işlevi içermesi gerekir mi? Lambda ifadelerini cevap olarak kullanıyorum.
Makotosan

3
@Makotosan Hayır, hayır; Lambdalar genelde iyidir.
daniero

21

Boole ifadelerini kullanmak zorunda kalırsanız trueveya sırasıyla ve falseile değiştirin .1>01<0

Örneğin:

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

Bu doğrusal arama örneği,

boolean f=1<0;
for(i=0;i<10;)if(a[i++]==42)f=1>0;

11
Çok ihtiyacın olacaksa true/false, sadece ekle boolean t=1>0,f=1<0;. Ardından, yerine 1>0kullanın tve kullanım başına iki karakter kaydedin. Payoff over 1>0yöntemi 10 kullanımda geliyor.
Geobits

24
@ Geobits: boolean t=1>0,f=!t;- Bir karakter daha kısa!
bobbel

6
Örnek gerçekten iyi değil. Bu durumda ve (!) Diğerleri zaten true/ falsedoğrudan kullanmaktan kaçınabilirsiniz : f|=a[i++]==42;oldukça tasarruf sağlar.
Ingo Bürk

@ IngoBürk Doğru. Bunu yazarken çoğunlukla kullanılan kütüphane fonksiyonlarını düşünüyordum boolean, ama yazarken hiçbir örnek bulamadım (genellikle Java'da kodlamıyorum) basit bir örnek yazdım.
ace_HongKongIndependence 30:14

1
@Geobitler java ile aşina değil ama sadece 1 tanımlıyor ve t ve! T kullanıyor musunuz (tekrar Java bilmiyorum, sadece merak ediyorum)
Albert Renshaw

20

Bazı yöntemleri çok fazla kullanacaksanız, yerleşik sınıfını bir değişkene atayın. Örneğin, System.outbir değişkene atayın :

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

Ayrıca Integer.parseInt():

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

Bu neredeyse kesinlikle "değişkenden statik yönteme erişme" hakkında bir ide uyarısını tetikleyecektir


((Integer)1).parseInt("1")de çalışır.
Magic Octopus Urn

5
@ carusocomputing new Integer("1")daha da kısa. Ancak Justin'in cevabını kastettiği, zaten statik çağrılar için sahip olduğunuz değişkenleri tekrar kullanabilmenizdir. Bu cevabın alt kısmında açıkladığım gibi.
Kevin Cruijssen

19

İfadelerden import static java.lang.System.*tasarruf etmek için tekniği kullanmak yerine println(), aşağıdaki yöntemi tanımlamanın karakterleri kaydetmede çok daha etkili olduğunu gördüm:

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

Bunun nedeni , daha hızlı ve daha dramatik bir karakter kazancına sahip olması p(myString)yerine çağrılabilir out.println(myString).


19

Bu açık görünebilir, ancak bazı Mathişlevler için daha kısa seçenekler vardır :

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

14

Gerekirse Integer.MAX_VALUE(2147483647) kullanın -1>>>1. Integer.MIN_VALUE(-2147483648) daha iyi yazılmıştır 1<<31.


14

Bir argümandan (veya başka bir dizeden) bir sayı almanız gerekirse, normal olarak şöyle bir şey görürsünüz:

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

Çoğu zaman, bir ihtiyacınız yok Integer. Çok sayıda zorluk çok fazla kullanmıyor. Yana Shortve Bytebir hem Unbox olacak int, daha uygun kullanmak valueOf()yerine ve bir çift bayt kaydedin.

Gerçek tutun değişken bir şekilde inthem daha kısa olduğundan, yine de, byteve short:

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

Bunu birden fazla numara için yapmanız gerekirse, bu yöntemle birleştirebilirsiniz :

Byte b=1;
int n=b.valueOf(a[0]),m=b.valueOf(a[1])...

9
int n=new Byte(a[0]);üç kısa. Sayı daha büyük olabilirse , çoğu durumda s'den long n=new Long(a[0])daha iyidir int.
Ypnypn

14

Kullanmayın public class. Ana yöntemin halka açık olması gerekir, ancak sınıfı değildir. Bu kod çalışıyor:

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

Genel bir sınıf java Solmasa bile koşabilirsiniz class S. ( Güncelleme: Bu ipucunu yazdığımda Java 7 kullanıyordum. Java 8'de ana yönteminiz bir arayüzde olmalı . Java 5 veya 6'da, ana yönteminiz bir enumda olmalıdır .)

Bir sürü Java programcısı bunu bilmiyor! Herkese açık olmayan bir sınıftaki Yığın Taşması sorusuna verilen cevapların yaklaşık yarısı, ana yöntemin bir ortak sınıfta olması gerektiğini iddia ediyor. Şimdi daha iyi biliyorsun. Sil publicin public classve 7 karakterleri kaydedin.


1
1.8'den önce bir Java'yı hedeflemediğiniz sürece yapı interface s{static void main(String[]...daha kısadır. Derlenebilir bir kaynak dosyanız ve ana yönteminiz varsa. Çünkü bir Java 1.8 arayüzünde, tüm yöntemler ortaktır, böylece değiştiricileri yöntem (ler) de atlayabilirsiniz.
Douglas

Son zamanlarda Java kullanmadım, bu yüzden cevabım modası geçmiş oluyor. Ben arayüzleri Java 8. yöntemleri olabileceğini unutmuşum
kernigh

Programlamadan öğrenmedim; Ben golf oynamaktan öğrendim :)
Douglas Held

14

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 .


Daha genel olarak son noktanız için, statik üyelere, nesnenin bir örneği gibi statik olmayan bir bağlamdan erişebilir / bu bilgileri çağırabilirsiniz.
Poke

1
Tavan ipucunu anlamıyorum. Neden tavana geçmek istiyorsun positive integers? Ayrıca, tavan uygulamasının işe yarayıp yaramadığından emin değilim .
Jonathan Frech

1
since Java automatically floors on integers; Bence uygun terim, döşeme değil , kısaltmadır .
Jonathan Frech

1
Başka bir Palindrome stratejisiString t="";for(int i=s.length();--i>=0;t+=s.charAt(i));return s.equals(t);
Roberto Graham

1
@RobertoGraham Aslında orijinal kodumu yanlış girişten kopyaladım .. Sadece s.equals(new StringBuffer(s).reverse()+"")yeterli.
Kevin Cruijssen

11

Giriş gerektirmeyen golf oynamak için, statik blokları kullanabilir ve herhangi bir ana yöntem kullanmadan çalıştırabilirsiniz, Java 6 ile derleyin.

public class StaticExample{
    static {
        //do stuff
    }
}

1
Derlemeye ve çalıştırmaya çalıştınız mı? Bu blok, sınıf sınıf yükleyici tarafından yüklendiğinde çalıştırılır. Ancak sınıf yükleyici, ana yöntemi olan bir sınıf öğrenene kadar hiçbir şey yüklemez.
Cruncher

@Cruncher Kendinizi javakomut satırında / hangi sınıfın yükleneceğini bildireceğiniz bir manifesto dosyasında söyleyerek halledebilirsiniz .
AJMansfield

6
@Cruncher, bu Java 6 ile çalıştı. Java 7 çalışma şeklini değiştirdi.
Peter Taylor

1
Sonunda bir istisna atar ama işe yarıyor! Java 7'de bile
stommestack

2
@JopVernooij Eğer yüzünüze bir istisna atmak istemiyorsanız, system.exit () karakterini boşa harcayamazsınız, ancak karakterleri israf edersiniz, hiç bir golf mücadelesi istisnaları önlemek
istemez

11

Hepimiz bitwise xor ( ^) yöntemini biliyoruz , ama aynı zamanda mantıklı bir xor.

Yani (a||b)&&!(a&&b)sadece olur a^b.

Şimdi xor kullanabiliriz.

Ek olarak , operatörler |ve & ayrıca çalışırlar , sadece operatör önceliğinin değiştiğini unutmayın.


5
Önceliğini hatırladığınız sürece ve kullanabilirsiniz . Koşullarınız zaten parantez içine alınmışsa veya zaten booleanlarla çalışıyorsanız faydalı olabilir. &|
Geobits

1
Eğer (çok) daha düşük bir önceliğe ihtiyacınız varsa, xor !=yerine ^ve ==xnor için kullanabilirsiniz
Cyoce

11

Kullanmak zorunda değilsin Character.toLowerCase(char c). Bunun yerine kullanın (c|32). Yerine Character.toUpperCase(char c)kullanımı (c&~32). Bu sadece ASCII harfleriyle çalışır.


c|~32-1 ile sonuçlanma eğiliminde olurdu ... kullanımı daha iyi c-32.
feersum

5
@ feersum Büyük harfli bir büyük harf yapmak istemeniz işe yaramaz.
TheNumberOne

11

Dize sayıya dönüştürme

Bir String'i sayısal bir değere dönüştürmenin birden fazla yolu vardır:

String s = "12";

ABC.parseABC :

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

ABC.valueOf :

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

yeni abc :

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

Bu nedenle, kod golf oynamak için, bir String'i sayısal bir değere dönüştürürken yapıcıyı kullanmak en iyisidir.

Aynısı için de geçerlidir Double; Float; ve Byte.


Zaten mevcut olan bir ilkeli nesne olarak yeniden kullanabiliyorsanız bu her zaman geçerli olmaz.
Örnek olarak, şu kodumuz olduğunu varsayalım:

// 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
}

.decodeParametreyi nesne olarak yeniden kullanarak daha kısa yapıcı yerine kullanabilirsiniz :

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
}

10

Kullanma Random!

Genel olarak, rastgele sayılara ihtiyacınız varsa, Randombunun hakkında gitmek için korkunç bir yoldur *. Math.random()Bunun yerine kullanmak çok daha iyi . Kullanmak için Random, bunu yapmanız gerekir (diyelim ki bir ihtiyacımız var int):

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

Şunu karşılaştırın:

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

ve:

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

İlk yöntem 41+15nkarakterleri alır ( narama sayısıdır). İkincisi 25nkarakter, üçüncüsü 43+7n.

Bu nedenle, yalnızca bir veya iki defa ihtiyacınız varsa, satır içi Math.random()yöntemi kullanın . Üç veya daha fazla arama için, bir işlev kullanarak tasarruf edersiniz. Ya tek karakterleri kaydeder ilk kullanım üzerine Random.


Zaten Math.random()için doublekullanıyorsanız, dört kullanımda, onu içine çekmek için hala bir tasarruf olduğunu unutmayın:

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

33 karakter için, yaptığınız her aramada 10 r()


Güncelleme

Bir tamsayıya ihtiyacınız varsa ve dökümden tasarruf etmek istiyorsanız, döküm yapmayın! Atama yerine bir işlem yaparsanız Java otomatik atma yapar. Karşılaştırmak:

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

* Öngörülebilir sonuçlar için PRNG'yi tohumlamanız gerekmiyorsa. O zaman, çevresinde pek bir yol görmüyorum


2
Random#nextGaussianYine de unutma .
Justin,

@ Quincunx Doğru, iyi bir normal dağılım elde etmek için matematiği yapmak, elde ettiğiniz tasarrufları kaybeder. Ben sadece kuralı kanıtlayan bir istisna olarak göreceğim;)
Geobits

(int)(Math.random()*9)Çok küçük bir modulo önyargıya sahip olduğuna dikkat edin , çünkü Math.random()2 53 olası değerleri döndürür ve 2 53 9'un katı değildir. Her sayının olasılığı 1/9 artı veya eksi 5 / (9 * 2 ** 53), çok küçük bir hata, neredeyse tam olarak 1/9.
kernigh

@kernigh Doğru, 9sadece bir örnek olarak kullanıyordum , her şey olabilirdi. Java'nın PRNG'sinin çalışmasından dolayı nextInt()(veya başka bir Randomyöntemin) de küçük bir önyargıya sahip olduğuna nispeten eminim .
Geobits,

1
Rasgele bir boolean istediğinizde ilgili bir şey: yerine new java.util.Random().nextBoolean()kullanabilirsiniz Math.random()<.5.
Kevin Cruijssen,

7

Bu 'saf' Java'yı düşünür müsünüz bilmiyorum, ancak İşleme çok az başlangıç ​​ayarlı programlar oluşturmanıza olanak tanır (otomatik olarak tamamlanır).

Konsol çıktısı için aşağıdaki kadar basit bir şeye sahip olabilirsiniz:

println("hi"); //done

grafik çıktı için biraz daha:

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
}

1
+1 Mükemmel kaynak! Onunla oynamak için emin olacağım.
Rob

Buna başkalarının cevaplarını eklesem olur mu? Yoksa bu bir topluluk vikisinin amacını bozuyor mu?
Rob

2
Bu arada, hiç aramanıza gerek yok size; 100 x 100 piksel kare için varsayılan olacaktır. Çoğu işletim sisteminde, etrafındaki çerçeve kare ortalanmış ve alanın geri kalanı masaüstünden alınan içerikle dolu olacak şekilde yaklaşık iki kat daha büyük olacaktır.
AJMansfield

1
Grafiksel çıktı için, animasyona ihtiyacınız yoksa, dışındaki her şeyi yazabilir setup()ve draw()"statik modu" kullanabilirsiniz. Ayrıca 6 basamaklı onaltılık renkleri kullanabilir ve tercüman bazen (amorti hangi bunları değiştirecek #FF8000< 255,128,0) ve gri tonlama kullanıyorsanız yalnızca bir sayı belirtilmesi gerekir ( 255< 255,255,255)
kuat

7

Geri dönen kısalma

Dizelerin dönüş ifadelerini bir bayt ile kısaltabilirsiniz:

return "something";

için

return"something";

Ayrıca return ifadesine parantezle başlarsanız, onlarla aynı şeyi yapabilirsiniz:

return (1+taxRate)*value;

için

return(1+taxRate)*value;

Sanırım tırnak parantez içinde sayılıyor mu? Aslında bunu yeterince AppleScript aracılığıyla aldım, yeterince komik ve bahsetmeye değeceğini düşündüm.


1
Aynısı, return-n;yerine return -n;veya return~n;yerine sayı işaretleri için de geçerlidir return ~n;. Çift tırnak yerine tekli olarak:return'A';
Kevin Cruijssen

1
Temel olarak, tanımlayıcının parçası olamayacak herhangi bir şey için çalışır (örn. Harf olmayan ve rakamsız).
Paŭlo Ebermann

7

Bilimsel gösterimi kullanmaktan korkma

Çiftlerle ya da yüzmelerle ilgileniyorsanız, sayılar için bilimsel gösterimi kullanabilirsiniz. Yani yazmak yerine 1 byte tasarruf double a=1000etmek double a=1e3için değiştirebilirsiniz .


7

Kullanmayı deneyin intyerineboolean

Bazı durumlarda, C programlarında yapılabileceklere benzer şekilde, normalde bir boole döndürecek bir yöntemden bir tamsayı değeri döndürmenin daha kısa olduğunu buldum.

Yarasa hemen kapalı int4 bayt daha kısadır boolean. return 0Bunun yerine her return 1<0yazışınızda, ek 2 bayt kaydedersiniz ve bu işlem return 1 bitti return 1>0.

Buradaki sorun, geri dönüş değerini doğrudan bir boole olarak kullanmak istediğinizde, 2 bayt ( if(p(n))v. if(p(n)>0)) Olmasıdır . Bu, boole aritmetiği kullanılarak yapılabilir. Yazmak istediğiniz yerleşmiş bir senaryo verildiğinde

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

bunun yerine yazabilirsiniz

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

2 bayt kaydetmek için.


6
Ben golf zaman çok sık bunu ancak unutmayın genel bir konsensüs olduğunu 0ve 1Java / yanlış doğrudur teşkil etmez (ve JLS ya onlara bu şekilde dikkate almaz). Bu nedenle, eğer golf özellikle hakikat / falsi istiyorsa, onu booleanize etmeniz gerekir (ve ne yazık ki, ona booleandaha fazla bayt atan bir fonksiyon yapmalısınız).
Geobits

2
t[0]+=p(n):10?0;Bu bile geçerli mi?
dorukayhan

@dorukayhan hayır, olması gerekiyordu t[0]+=p(n)?10:0;. (Düzenledim.)
Paŭlo Ebermann

6

Eğer kullanırsanız yerine sınıfın enum , bir karakter kaydedin.

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

    }
}

Ancak, kendilerine ödeme yapması gereken en az bir enum örneği (bu örnekte F, G, H) tanıtmanız gerekir.


2
Enum örneğine ihtiyacın yok gibi görünüyor. Yaptığım enum M{;public static void main(String[]a){...}hiçbir sorunları ile.
Danny

3
@Danny Ama sonra herhangi bir karakter kaydetmiyor. class M{tam olarak aynı uzunluktadır enum M{;. Bu durumda, ben ile gitmek istiyorum classçünkü daha güzel (IMO)
Justin 23

1
en azından benim enum{için ;sonra olmadan çalıştı ; sadece bir hata olduğunu inleyen IDE'dir, ancak derleyici bunu kabul eder
masterX244

@ masterX244 Hangi derleyici / sürüm? Maden sinir krizi atar ve yapmaz.
Geobits

(.8 bir güncelleme ile daha da nedenini araştırmak için ned s çıktı çalışma durduruldu) benim için java 1.7 üzerinde çalıştı
masterX244

5

Eğer bir dönmelidir bir yöntem varsa booleanOr Boolean, yani:

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

Değişebilirsin boolean/ Booleandönüş tipi Object1 baytı kaydetmek için:

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

Ayrıca, fark etmiş olabileceğiniz gibi, bayt kaydetmek <1yerine bir çek kullanabilirsiniz ==0. Her ne kadar bu, Java'ya özgü yerine genel bir kod golf ucu olsa da.
Bu, çoğunlukla tamsayı negatif olamadığında kullanılır, örneğin uzunluk kontrolü gibi:

a.length<1

onun yerine

a.length==0

1
Güzel ipucu! Geçerli c(-21)olanla döndüğünden , göstermek için "negatif olamazsa" bölümüne başka bir örnek eklemek isteyebilirsiniz true.
Geobits,

Aydınlatılmış. Ayrıca, c(-20)yerine demek istemiyor musun -21? -21 % 5 = 4ve -20 % 5 = 0.
Kevin Cruijssen

1
Hayır demek istedim -21. -21 % 5 != 4Java, benim açımdan. Beş işlev tarafından bölünebilir olacağını modülü daima negatif olmayan döndü eğer düzgün çalışması, ama öyle değil. Bu örnek pasaja bakın .
Geobits,

@Geobits Ah, örnek için teşekkürler. Negatif sayıları neredeyse hiç kullanmam %, bu yüzden Java'nın modül yerine geri kalanı döndürdüğünü, dolayısıyla farkın olduğunu unuttum ..
Kevin Cruijssen

5

Java ile nasıl çizilir ...

İşte mümkün olan en kısa GUI boya kazan sacı:

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

111 Baytlık Golf Sahası:

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

5

önlemek StringBuilders

Bir şeyler için şeyler eklemek Stringçok daha az bayt alır.

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

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

Bir dizgeyi ters çevirip hemen yazdırmanız gerekirse, a kullanın 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

Bir dizgeyi ters çevirip basmaktan başka bir şey yapmanız gerekiyorsa, forher bir döngü kullanın .

String b=new StringBuffer("Hello, World!").reverse().toString();
String B="";for(String c:"Hello, World!".split(""))B=c+B;

3
Bir foreach döngüsü, StringBufferters dizgilerden daha kısadır . String b="";for(char c:"Hello, World!".toCharArray()){b=c+b;}
Poke

1
Bu {}yöntemi kullanacaksanız, bu foreach döngüsünden de kaldırmalısınız .
Geobits,

1
Kullanılarak 2 bayt kaydet String s:"".split("")yerine char c:"".toCharArray().
charlie

Eğer varsa java.util.stream.Streamzaten ithal Eğer sonuca zincire başka bir çağrı gerekiyorsa ve (gibi B.chartAt(42)sadece bir fonksiyonu (benzerine sonucu geçmesi gerekiyor ise) veya f(B)), sonra kullanarak for(:)etmek equall olduğunu Stream.of("Hello, World!".split("")).reduce("",(a,b)->b+a).
charlie

Örneğinizdeki her iki çizgi için de her biri golf oynayabilir. Birincisi olabilir: String b=new StringBuffer("Hello, World!").reverse()+"";(ile .toStringdeğiştirilir +"") ve ikinci çizginiz olabilir: String B="";for(String c:"Hello, World!".split(""))B=c+B;( charile Stringve .toCharArray()arasında .split("")).
Kevin Cruijssen

5

Java 10'ları kullanın var

Belirli bir türdeki tek bir değişkeni tanımlarsanız, kullanın var.

Örnekler

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

Aşağıdaki örneklerin hiçbirinde kullanılamaz

var birçok örnekte kullanılamaz

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)

Bunun neden yöntem referansları ile çalışmadığını açıklayın, yalnızca küçük bir imza kümesi için standart işlevsel arayüzlerin bulunduğunu unutmayın (ve yöntemler kontrol edilen istisnalar atabilir).
Jakob


4

Çoğu durumda, programınız tek iş parçacıklı olacaktır, yani yalnızca bir iş parçacığı çalışacaktır. Bu returndurumdan, anında çıkmak zorunda olduğunuz ana yöntemden yararlanarak yararlanabilirsiniz .

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

Programı sonlandırmak için "uygun" olarak karşılaştırın:

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

Veya işaret null:

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

Veya 0'a bölünerek:

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

4

Bazen, tek bir döngü for ifadesi değiştirilebilir olabilir. Aşağıdaki kodu göz önünde bulundurun:

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

Bu, bu sorunun çözümü olan basit bir döngüdür .

iStackOverflow hatalarına neden olacak kadar büyük olmayacağını bildiğimiz için for-loop'u özyineleme ile değiştirebiliriz:

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

Yinelemeye neden olmak için return ifadesinde üçlü bir operatör kullanarak bir döngüyü simüle edebiliriz.

Bu azalma oldukça spesifik, ancak bunun işe yarayacağı daha fazla durum hayal edebiliyorum.


4

...Parametre olarak (varags) kullanmak

Bazı durumlarda, Java varargs'ı gevşek olanlar yerine parametre olarak kullanmak daha kısa sürer.
Örneğin:

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

Bu çoğunlukla golf tarafından olurdu:

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

Ancak buna ek bir bayt golf oynayabilir:

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

Üç tamsayının tümüne yöntemin kendisinde yalnızca bir kez erişildiğine dikkat edin. Yana intoldukça kısadır yöntem içinde sadece bir kez onları her kullanın ve üç veya parametre olarak onlardan daha varsa sadece faydalıdır.

Daha uzun parametrelerde bu genellikle daha faydalıdır. Örneğin, bu, bu zorluk için orjinal cevabımdı (giriş dizesindeki girdi karakterinin oluşumunu hesapla):

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

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

Ve bununla golf oynaması önerildi:

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

Ama şunu kullanarak golf oynadım ...:

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

NOT: Soru / meydan okuma esnek bir girdi isterse , elbette ...kısaltılabilir []. Soru / meydan okuma özellikle sorarsa, diyelim ki, üç Stringgirdi Stringiçeren ve üç değer içeren bir dizgiyi geçersiz kılar, String...bunun yerine kullanabilirsiniz String a,String b,String c.


2
String[]Varargs kullanmak yerine kullanamaz mısın? (1 bayt daha tasarruf sağlar)
Kritixi Lithos

@KritixiLithos Hmm .. iyi nokta. Ancak bu, temel olarak girdilerin zorluk için ne kadar esnek olduğuna bağlıdır. Herhangi bir giriş formatına izin verilirse, bundan daha kısa olacaktır. Bunu bu ipuçlarına ekleyeceğim, teşekkürler.
Kevin Cruijssen
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.