Javaで使用できる便利なショートカットはありますか?
以下に示すように、import
すでに少なくとも17文字がプログラムに追加されています。
import java.io.*;
簡単な解決策は別の言語を使用することであることを理解していますが、Javaプログラムを短縮することは本当に難しいようです。
ヒントはJavaに固有である必要があります。ほとんどのCライクな言語に適用できる場合は、より一般的なヒントのリストに属します。
Javaで使用できる便利なショートカットはありますか?
以下に示すように、import
すでに少なくとも17文字がプログラムに追加されています。
import java.io.*;
簡単な解決策は別の言語を使用することであることを理解していますが、Javaプログラムを短縮することは本当に難しいようです。
ヒントはJavaに固有である必要があります。ほとんどのCライクな言語に適用できる場合は、より一般的なヒントのリストに属します。
回答:
可能な限り最新のjavaを使用してください。Java 8ではラムダ式を使用できるため、機能オブジェクトのようなものが必要な場合に使用します。
よく使うものの短縮機能を定義します。たとえば、を100回呼び出してexampleClassInstance.doSomething(someParameter)
、新しい関数void d(ParameterType p){exampleClassInstance.doSomething(p)}
を定義し、それを使用していくつかの文字を保存します。
特定の長いクラス名を複数回使用している場合、たとえば
MyEventHandlerProxyQueueExecutorServiceCollectionAccessManagerFactory
代わりに、新しいクラスを定義します。
class X extends MyEventHandlerProxyQueueExecutorServiceCollectionAccessManagerFactory{}
そのクラスの特定のメソッドを1つだけ使用している場合(それでもインスタンス化する必要がある場合)、同時に新しいクラス内で短縮バージョンを定義できます。
可能な場合は、次のように関数型パラメーターを使用して短縮します。
<T>void p(T o){System.out.println(o);}
のfor(;;)
代わりに使用しますwhile(true)
。
絶対に必要でない限り、アクセス修飾子を使用しないでください。
final
何にも使用しないでください。
for
ループの後にブロックを配置しないでください(ただしforeachループfor(x:y)
は異なります)。のfor
ように、ステートメント自体の中に追加のステートメントを配置する必要がありますfor(int i=0;i<m;a(i),b(++i))c(i);
。
インラインの割り当て、増分、インスタンス化を使用します。必要に応じて、匿名のインラインクラスを使用します。可能であれば、代わりにラムダを使用してください。ネスト関数呼び出し。一部の関数は、親オブジェクトを返すことが保証されています。これらの関数は、実際にはチェーン化されることさえ意図されています。
あなたのmain
方法throws Exception
の、それらをキャッチしていません。
Error
はより短いException
。何らかの理由で本当にthrow
メッセージをスタックに上げる必要があるError
場合は、完全に正常な状況であってもを使用します。
すぐに終了する必要がある条件がある場合int a=1/0;
は、throw null;
またはではなくを使用しますSystem.exit(0);
。実行時に、これはをスローしArithmeticException
ます。コードに数値変数が既にある場合は、代わりに使用します。(既にお持ちの場合はimport static java.lang.System.*;
、に進みexit(0);
ます。)
のようなインターフェースを実装する代わりに、ほとんどのメソッドのデフォルトの実装を提供し、以下の実装のみを必要とするのようなList<E>
即時の(または、そうすることに利点がある場合はそれほど即時ではない)子クラスを拡張AbstractList<E>
しますいくつかの重要な部分。
改行、インデント、および完全な変数名を使用して、最初に手書きでコードを記述します。作業コードを作成したら、名前を短縮したり、宣言を移動したり、ショートカットメソッドを追加したりできます。開始するまで長く書くことで、プログラム全体を単純化する機会が増えます。
コードのごくわずかな変更で最適な戦略が劇的に変わる可能性があるため、代替の最適化をコードと比較してください。例えば:
Arrays.sort(a)
場合、最も効率的な方法は、完全修飾名で呼び出すことjava.util.Arrays.sort(a)
です。void s(int[]a){java.util.Arrays.sort(a);}
です。この場合、これでも完全修飾名を使用する必要があります。(複数のオーバーロードが必要な場合は、おそらく間違っています。)for
、ゴルフの短いループで、簡単にアクセスできるライブラリメソッドがない場合)、Arrays.copyOf
タスクを実行するために利用できます。複数のメソッドが使用され、3つ以上の呼び出しがある場合、実行import static java.util.Arrays.*;
がこれらのメソッドを参照する最も効率的な方法です。その後、8つ以上の個別の呼び出しがsort
ある場合にのみ、ショートカットメソッドを使用する必要があり、5つ以上の呼び出しでのみ、ショートカットが保証されcopyOf
ます。コードでこのような分析を実行する唯一の実際の方法は、コードのコピーで潜在的な変更を実際に実行し、結果を比較することです。
someTypeValue.toString();
メソッドの使用を避け、代わりに単にappendしますsomeTypeValue+""
。
ウィンドウが必要な場合は、Swingを使用せず、AWTを使用します(Swingの何かが本当に必要な場合を除く)。とを比較import javax.swing.*;
しimport java.awt.*;
ます。さらに、Swingのコンポーネントには、J
名前の前に追加されます(JFrame
、JLabel
など)が、AWTのコンポーネントがいない(Frame
、Label
など)
のinterface
代わりに使用しますclass
。
Java 8では、静的メソッドがインターフェイスに追加されました。インターフェイスでは、すべてのメソッドはデフォルトでパブリックです。その結果
class A{public static void main(String[]a){}}
今に短縮することができます
interface A{static void main(String[]a){}}
これは明らかに短いです。
たとえば、Hello、World!でこの機能を使用しました。チャレンジ。
では可変引数あなたは、同じ型の配列にパラメータを「キャスト」することができます:
void f(String...x){
x=x[0].split("someregex");
// some code using the array
}
の代わりに
void f(String s){
String[]x=s.split("someregex");
// some code using the array
}
静的インポート:
import static java.lang.System.out;
// even shorter (thanks to Johannes Kuhn):
import static java.lang.System.*;
後から定型句を保存できますが、見返りを得るには複数の呼び出しが必要です。
public static void main (String[] args) {
out.println ("foo");
out.println ("bar");
out.println ("baz");
}
Java
!
import static java.lang.System.*
。
var o=System.out;
唯一それが報わ前に2回使用する必要がある
var o=System.out.println
動作しますか?
ブール式true
またはを使用する必要がある場合は、それぞれfalse
を1>0
and に置き換えます1<0
。
例えば:
boolean found=false;
for(i=0; i<10; i++) if(a[i]==42) found=true;
この線形検索の例は、
boolean f=1<0;
for(i=0;i<10;)if(a[i++]==42)f=1>0;
true/false
、単に追加してくださいboolean t=1>0,f=1<0;
。次に、の代わりに1>0
、使用t
ごとに2つの文字を使用して保存します。支払い1>0
方法は10回使用できます。
boolean t=1>0,f=!t;
文字短く!
true
/をfalse
直接使用することを避けることができます:f|=a[i++]==42;
かなり節約できます。
boolean
ていましたが、執筆時にどんな例も思いつかなかったので(私は通常Javaでコーディングしません)、私は簡単な例を書いただけです。
何らかのメソッドを頻繁に使用する場合は、その常駐クラスを変数に割り当てます。たとえばSystem.out
、変数に割り当てます。
java.io.PrintStream o=System.out;
//now I can call o.print() or o.println() to the same effect as System.out.println()
また、用Integer.parseInt()
:
Integer i=1;
i.parseInt("some string");
これにより、「変数から静的メソッドにアクセスする」というIDE警告がほぼ確実にトリガーされます。
((Integer)1).parseInt("1")
も動作します。
new Integer("1")
はさらに短くなります。しかし、Justinが彼の答えで意味したのは、既に持っている変数を静的呼び出しに再利用できるということです。この答えの一番下で説明するように。
引数(または他の文字列)から数値を取得する必要がある場合、通常は次のように表示されます。
public static void main(String[]a){
int n=Integer.valueOf(a[0]);
...
}
多くの場合、あなたはしていない必要がありますInteger
。たくさんの課題が大きな数字を使うことはありません。以来Short
とByte
の両方のVHS版はなりint
、より適切なを使用valueOf()
代わり、数バイト節約します。
ただし、実際の変数はとして保持します。int
これは、byte
およびの両方よりも短いためshort
です。
int n=Byte.valueOf(a[0]);
複数の番号に対してこれを行う必要がある場合は、このメソッドと組み合わせることができます。
Byte b=1;
int n=b.valueOf(a[0]),m=b.valueOf(a[1])...
int n=new Byte(a[0]);
3つ短いです。数値が大きくなる可能性がある場合は、を使用しますがlong n=new Long(a[0])
、int
ほとんどの場合はs よりも優れています。
使用しないでくださいpublic class
。メインメソッドはパブリックである必要がありますが、そのクラスはパブリックではありません。このコードは機能します:
class S{public static void main(String[]a){System.out.println("works");}}
あなたは実行できjava S
ていてもclass S
公共のクラスではありません。(更新:このヒントを書いたときにJava 7を使用していました。Java8では、メインメソッドはインターフェイスにある必要があります。Java5または6では、メインメソッドはenumにある必要があります。)
多くのJavaプログラマーはこれを知りません!非パブリッククラスのメインに関するStack Overflowの質問に対する回答の約半分は、メインメソッドがパブリッククラスにある必要があると誤って主張しています。今、あなたはよく知っています。削除public
中のpublic class
7つの文字を保存します。
interface s{static void main(String[]...
は短くなります。コンパイル可能なソースファイルとメインメソッドが必要な場合。Java 1.8インターフェースでは、すべてのメソッドがパブリックであるため、メソッドの修飾子をスキップできます。
これらのヒントは個別の回答には少し小さすぎたので、この回答を、私が見つけた、または思いついた非常に小さなコードゴルフのヒントに使用します。他のヒントにはまだ触れていません。
// I used to do something like this:
s.substring(0,s.length()-1) // 27 bytes
// But this is shorter:
s.replaceAll(".$","") // 21 bytes
場合によっては、最後の文字が何であるかを事前に知っており、この文字が文字列で1回しか出現しないことも知っています。その場合、.split
代わりに使用できます:
// As example: "100%" to "100"
s.split("%")[0] // 15 bytes
// 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
すべてのエンコーディングには、java.nio
APIで使用される正規名と、APIで使用される正規名がjava.io
ありjava.lang
ます。以下は、Javaでサポートされているすべてのエンコーディングの完全なリストです。したがって、常に2つのうち最短のものを使用してください。2番目は通常短い(UTF-8
vs utf8
、Windows-1252
vs Cp1252
など)ですが、常に(UTF-16BE
vs UnicodeBigUnmarked
)ではありません。
// 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
プライムをチェックしたり、すべてのプライムを取得したりする方法はたくさんありますが、ここでの@SaraJの答えは最短です。参照用のコピー&ペーストは次のとおりです。
// 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*/;}}
注:通常、使用方法に応じて、他の既存のループとマージできます。そのため、別の方法は必要ありません。これにより、たとえばこの回答で多くのバイトが節約されました。
あなたが使用している場合は、正ダブルス/山車を、あなたがしたいfloor
それら、使用していないMath.floor
が、使用(int)
(Javaは、整数に切り捨てので)代わりに-castを:
double d = 54.99;
int n=(int)Math.floor(d); // 25 bytes
int m=(int)d; // 13 bytes
// Outputs 54 for both
代わりに、同じトリックを負の double / floatに適用できますceil
。
double d = -54.99;
int n=(int)Math.ceil(d); // 24 bytes
int m=(int)d; // 13 bytes
// Outputs -54 for both
&1
代わりに使用して%2
、括弧を取り除きます。なぜなら演算子の優先順位の&
のようなデフォルトの算術演算子よりも低くなっている*/+-
と%
、あなたはいくつかのケースでは括弧を取り除くことができます。
// So instead of this:
(i+j)%2 // 7 bytes
// Use this:
i+j&1 // 5 bytes
これはブールチェックでは実際には役に立たないことに注意してください。そうすれば、括弧が必要になりますが、それらは少し移動するだけです。
(i+j)%2<1 // 9 bytes
(i+j&1)<1 // 9 bytes
BigIntegerを使用する場合は、一度だけ作成してから再利用できます。ご存知かもしれませんが、BigIntegerにはZERO
、ONE
およびの静的フィールドが含まれていますTEN
。したがって、これら3つだけを使用する場合は、必要はありませんimport
が使用できますjava.Math.BigInteger
直接。
// 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
注:使用する必要があります =null
ためにt
はを初期化する必要がありますt.
。
バイトを節約するために、複数のBigIntegerを追加して別のBigIntegerを作成できる場合があります。だから、BigIntegerを持ちたいとしましょう1,10,12
、何らかの理由で:
// 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
コメントで正しく指摘されているように、BigInteger t=null;
静的メソッド呼び出しのトリックは他のクラスでも使用できます。
たとえば、2011年の次の回答はゴルフにかけることができます。
// 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()
の代わりに toCharArray()
文字列の文字をループするには、通常これを行います。
for(char c:s.toCharArray()) // 27 bytes
// or this:
for(String c:s.split("")) // 25 bytes
文字をループすることは、文字を印刷したり、文字列などに追加するときに便利です。
あなたが唯一のいくつかのUnicode-数の計算のための文字を使用する場合は、あなたは置き換えることができchar
てint
、そして、あなたは置き換えることができtoCharArray()
てgetBytes()
:
for(int c:s.getBytes()) // 23 bytes
または、Java 8以降ではさらに短くなります。
s.chars().forEach(c->...) // 22 bytes
Java 10以降では、印刷する文字をループすることも22バイトで実行できるようになりました。
for(var c:s.split("")) // 22 bytes
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
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
!=
StringsでJavaの値の代わりに参照をチェックする場合、なぜこれが機能するのですか?のでString#trim
戻ります「先頭とホワイトスペースを削除末尾、またはでこの文字列のコピーを、それが何の先頭または末尾に空白がない場合、この文字列。誰かが私にこれを提案した後、」私はで、これを使ってきた私のこの回答。
文字列が回文であるかどうかを確認するには(文字列の偶数と奇数の両方の長さを念頭に置いて)、これが最短です(.contains
文字列自体とその逆の形式が等しい長さであるため、ここで動作します)。
String s=...;
s.contains(new StringBuffer(s).reverse()) // 41 bytes
.contains(...)
ここで@assyliasのコメントに.equals(...+"")
感謝する代わりに。
私はすでにこれを知っていると思います:どちらかa
またはb
ゼロかどうかを確認したい場合は、代わりに乗算してバイトを節約します:
a==0|b==0 // 9 bytes
a*b==0 // 6 bytes
そして、あなたは両方のかどうかを確認したい場合a
やb
ゼロであり、あなたはビット単位-ORを使用することができ、または、彼らは常に正であればそれらを一緒に追加します。
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:
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
私がこれを追加する理由はk+(k%2<1?1:-1)
、この答えを見た後です:
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
n
フルプログラムのループ時間完全なプログラムが必須であり、特定の回数ループする必要があるという課題がある場合、次のことができます。
// 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
この範囲を入力として取得する必要がある場合も同じです。
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
あなたが使用できない場合throws Exception
だけに持っているcatch
と、あなたが使用することができます返す前にそれで何かを行うfinally
代わりに:
try{...}catch(Exception e){return ...;} // 33 bytes
try{...}finally{return ...;} // 22 bytes
を使用する場合の例として、この答えをtry-catch
参照できます(間接ゴルフのクレジットは@KamilDrakariになります)。この課題では、NxM行列を斜めにループする必要があるため、列の量または行の量がforループの最大値として最も低いかどうかを判断する必要があります(バイトの点で非常に高価です)。したがって、単にusingをキャッチすることは、このチェックよりも短いため、バイトを節約できます。i<Math.min(a.length,a[0].length)
ArrayIndexOutOfBoundsException
catch-finally
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
注:これreturn r;
は、最終的にのみ機能しました。@KamilDrakariがC#の回答でバイトを節約するためにしたように、私は最初のセルを変更することを提案されました。ただし、Javaでは、これをm->{try{for(int i=1;;m[0][0]=f(m[0][0],m[i][i++]));}catch(Exception e){}}
(73バイト)に変更する必要があることを意味しますfinally
。
2の累乗が必要な場合、ビット単位のアプローチははるかに短くなります。
(int)Math.pow(2,n) // 16 bytes
(1<<n) // 6 bytes
Java(ブール)論理チェックの代わりに、およびJava(ブール)論理チェックで使用できることが今ではよく知られている&
と思います。場合によっては、エラーを防ぐためにの代わりに使用したい場合もあります。がここに変更される場合、配列内のインデックスを使用する部分を評価するため、が発生するため、この場合はの代わりにが使用されます。|
&&
||
&&
&
index >= 0 && array[index].doSomething
&&
&
ArrayIndexOutOfBoundsException
&&
&
これまでのJavaの&&
/ ||
vs &
/の基本|
。
をチェックする(A or B) and C
場合、最も短いものは次のようなビット単位の演算子を使用しているように見えます。
(A|B)&C // 7 bytes
ただし、ビット単位の演算子は論理チェックよりも演算子の優先順位が高いため、両方を組み合わせてここでバイトを保存できます。
A|B&&C // 6 bytes
n+=...-n
代わりに使用(long)...
を使用する場合など、ラムダの入力と出力の両方が長い場合Math.pow
、のn+=...-n
代わりにを使用してバイトを保存できます(long)...
。
例えば:
n->(long)Math.pow(10,n) // 23 bytes
n->n+=Math.pow(10,n)-n // 22 bytes
since Java automatically floors on integers
; 適切な用語は、フローリングではなく切り捨てだと思います。
String t="";for(int i=s.length();--i>=0;t+=s.charAt(i));return s.equals(t);
s.equals(new StringBuffer(s).reverse()+"")
十分です。
入力を必要としないゴルフでは、静的ブロックを使用し、メインメソッドなしで問題なく実行できます。Java6でコンパイルするだけです。
public class StaticExample{
static {
//do stuff
}
}
java
コマンドライン/マニフェストファイルでロードするクラスを伝えることで、それを回避できます。
を使用する必要はありませんCharacter.toLowerCase(char c)
。代わりにを使用してください(c|32)
。Character.toUpperCase(char c)
使用する代わりに(c&~32)
。これはASCII文字でのみ機能します。
c|~32
-1 ...を使用する方が良い結果になる傾向がありますc-32
。
文字列を数値に変換する方法は複数あります。
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
新しいABC:
new Short(s); // 13 bytes
new Integer(s); // 15 bytes
new Long(s); // 12 bytes
したがって、コードゴルフでは、文字列を数値に変換するときにコンストラクターを使用するのが最適です。
同じことが当てはまりDouble
ます。Float
; およびByte
。
既に存在するプリミティブをオブジェクトとして再利用できる場合、これは必ずしも当てはまりません。
例として、次のコードがあるとしましょう:
// 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
}
.decode
パラメータをオブジェクトとして再利用することで、より短いコンストラクタの代わりに使用できます。
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
}
使用しないでくださいRandom
!
一般的に、乱数が必要な場合Random
は、それを試す恐ろしい方法です*。Math.random()
代わりに使用することをお勧めします。を使用Random
するには、これを行う必要があります(が必要だとしましょうint
):
import java.util.*;
Random r=new Random();
a=r.nextInt(9);
b=r.nextInt(9);
それと比較してください:
a=(int)(Math.random()*9);
b=(int)(Math.random()*9);
そして:
int r(int m){return(int)(Math.random()*m);}
a=r(9);
b=r(9);
最初のメソッドは41+15n
文字を受け取ります(n
呼び出しの数です)。2番目は25n
文字で、3番目は43+7n
です。
したがって、1回か2回だけ必要な場合は、インラインMath.random()
メソッドを使用します。3回以上の呼び出しの場合、関数を使用して保存します。どちらかが最初の使用時に文字を保存しRandom
ます。
すでにMath.random()
for を使用している場合double
は、4回使用しても、次のように引き出すことで節約できることに注意してください。
double r(){return Math.random();}
33文字の場合、次の呼び出しごとに10を保存します r()
更新
整数が必要で、キャストを節約したい場合は、キャストしないでください!割り当ての代わりに操作を行うと、Javaが自動キャストします。比較:
a=(int)(Math.random()*9);
a=9;a*=Math.random();
* 予測可能な結果を得るためにPRNGをシードする必要がない限り。それから、私はそれのまわりの多くの方法を見ない。
Random#nextGaussian
。
(int)(Math.random()*9)
ため、モジュロバイアスは非常に小さいことに注意してください。各数値の確率は1/9プラスまたはマイナス5 /(9 * 2 ** 53)以内です。エラーは非常に小さいため、ほぼ正確に1/9です。Math.random()
9
ちょうど例として使用していました、それは何でもありえます。JavaのPRNGがどのように機能するかという理由だけで、nextInt()
(または他のRandom
方法でも)バイアスが小さいと確信しています。
new java.util.Random().nextBoolean()
を使用できますMath.random()<.5
。
この「純粋な」Javaを検討するかどうかはわかりませんが、Processingを使用すると、初期セットアップをほとんど必要とせずにプログラムを作成できます(自動的に完了します)。
コンソール出力の場合、次のような単純なものを使用できます。
println("hi"); //done
グラフィカル出力の場合、もう少し:
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
}
size
をする必要さえありません。デフォルトは100 x 100ピクセルの正方形です。ほとんどのOSでは、その周囲のフレームは約2倍の大きさで、正方形は中央にあり、残りの領域はデスクトップから取得したコンテンツで満たされています。
setup()
、draw()
「静的モード」の外ですべてを記述して使用できます。あなたはまた、6桁の16進の色を使用することができますし、通訳が時々 (報われ、それらを変更します#FF8000
< 255,128,0
)、そしてあなたがグレースケールを使用している場合のみ、1番号を指定する必要があります(255
< 255,255,255
)
以下を使用して、文字列のreturnステートメントをバイト単位で短縮できます。
return "something";
に
return"something";
そして、もし括弧でreturnステートメントを始めたら、それらで同じことをすることができます:
return (1+taxRate)*value;
に
return(1+taxRate)*value;
引用符は括弧のように考えられていると思いますか?私は実際にAppleScriptでこれを拾い上げました。
return-n;
の代わりに、return -n;
またはreturn~n;
代わりにreturn ~n;
。二重引用符ではなく単一引用符:return'A';
doubleまたはfloatを扱う場合は、数値に科学表記法を使用できます。だから書くのでdouble a=1000
はなく、それを変更することができますdouble a=1e3
1バイトを節約にます。
int
代わりに使用してみてくださいboolean
場合によっては、Cプログラムで行われることと同様に、通常ブール値を返すメソッドから整数値を返す方が短いことがわかりました。
すぐに、int
4バイトより短くなりboolean
ます。return 0
代わりに書くたびにreturn 1<0
、追加の2バイトを保存return 1
しreturn 1>0
ます。
ここでの落とし穴は、戻り値をブール値として直接使用するたびに2バイト(if(p(n))
v。if(p(n)>0)
)かかります。これは、ブール演算を使用して補うことができます。書きたいという人為的なシナリオを考える
void a(int[]t){t[0]+=p(n)?10:0;}
代わりに書くことができます
void a(int[]t){t[0]+=p(n)*10;}
2バイトを節約するため。
0
あり1
、Javaではfalse / trueを構成しないことを覚えておいてください(そしてJLSもそれらをそのように考慮しません)。したがって、ゴルフが特に真実/偽物を求めている場合は、それをブール化する必要があります(そして、残念ながら、それをboolean
機能にして、さらに多くのバイトを投げます)。
t[0]+=p(n):10?0;
これも有効ですか?
t[0]+=p(n)?10:0;
です。(私はそれを編集しました。)
classの代わりにenumを使用すると、1文字が保存されます。
enum NoClass {
F, G, H;
public static void main (String[] args) {
}
}
ただし、少なくとも1つの列挙型インスタンス(この例ではF、G、H)を導入する必要があり、それらは自分自身で成果を上げる必要があります。
enum M{;public static void main(String[]a){...}
問題なくやった。
class M{
は、とまったく同じ長さenum M{;
です。その場合、私はclass
それがきれいだから行きます(IMO)
enum{
は、;
アフターなしで働いていました。そこにエラーがあるbuttheコンパイラがそれを受け入れることうめき声その唯一のIDE
boolean
またはを返すメソッドがある場合Boolean
、つまり:
// Return true if the (non-negative) input is dividable by 5
boolean c(int i){return i%5<1;}
boolean
/ Boolean
return-typeを変更して、Object
1バイトを節約できます。
Object c(int i){return i%5<1;}
さらに、お気づきかもしれませんが、バイトを保存する<1
代わりにチェックを使用でき==0
ます。ただし、これはJava固有ではなく、より一般的なコードゴルフのヒントです。
これは、長さのチェックなど、整数を負にできない場合に主に使用されます。
a.length<1
の代わりに
a.length==0
c(-21)
ますtrue
。これは、現在の例で返されるためです。
c(-20)
代わりにの意味ではないです-21
か?-21 % 5 = 4
および-20 % 5 = 0
。
-21
。-21 % 5 != 4
私のポイントであるJavaで。モジュラスが常に非負を返した場合、5で割り切れる関数は正しく機能しますが、そうではありません。このサンプルスニペットを参照してください。
%
..ので、私は、Javaの代わりモジュラスの剰余を返し忘れ、従って差
以下は、最短のGUIペイントボイラープレートです。
import java.awt.*;
static void main(String[]x){
new Frame(){
public void paint(Graphics g){
// Draw your stuff here.
}
}.show();
}
import java.awt.*;static void main(String[]x){new Frame(){public void paint(Graphics g){/*CodeHere*/}}.show();}
StringBuilder
秒にデータを追加すると、String
必要なバイト数がはるかに少なくなります。
// s is a StringBuilder
s.append("Hello, World!");
// S is a String
S+="Hello, World!";
文字列を反転してすぐに印刷する必要がある場合は、を使用し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
文字列を反転し、それを印刷する以外のことをする必要がある場合は、for
各ループを使用します。
String b=new StringBuffer("Hello, World!").reverse().toString();
String B="";for(String c:"Hello, World!".split(""))B=c+B;
StringBuffer
文字列を反転する場合よりも短くなります。String b="";for(char c:"Hello, World!".toCharArray()){b=c+b;}
{}
そのメソッドを使用する場合は、foreachループからも削除する必要があります。
String s:"".split("")
代わりに2バイトを保存しますchar c:"".toCharArray()
。
java.util.stream.Stream
、すでにインポートされ、あなたがチェーンに結果への別のコール(等が必要な場合B.chartAt(42)
)、またはあなただけの機能(のように結果を渡す必要がある場合f(B)
)、その後、使用してはfor(:)
とequallですStream.of("Hello, World!".split("")).reduce("",(a,b)->b+a)
。
String b=new StringBuffer("Hello, World!").reverse()+"";
(に.toString
置き換えられ+""
ます)になり、2行目はString B="";for(String c:"Hello, World!".split(""))B=c+B;
(char
to String
と.toCharArray()
to .split("")
)になります。
var
特定のタイプの単一の変数を定義する場合は、を使用しますvar
。
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
var
多くの例では使用できません
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)
ほとんどの場合、プログラムはシングルスレッドです。つまり、実行中のスレッドは1つだけです。return
すぐに終了する必要がある場合は、メインメソッドからingすることでこの事実を活用できます。
static void main(String[]a){if(condition)return;}
プログラムを「適切に」終了することと比較してください。
static void main(String[]a){if(condition)System.exit(0);}
または次を指すnull
:
static void main(String[]a){if(condition)throw null;}
または0で割る:
static void main(String[]a){if(condition)int A=1/0;}
場合によっては、単一のforループステートメントが置き換え可能になる場合があります。次のコードを検討してください。
int m(int x){int i=1;for(;x%++i==0;);return i;}
これは、この質問の解決策である単純なforループです。
i
StackOverflowエラーを引き起こすほど大きくないことがわかっているため、代わりにforループを再帰に置き換えることができます。
int m(int x,int i){return x%++i>0?i:m(x,i);}
returnステートメントで三項演算子を使用して再帰を引き起こすことにより、ループをシミュレートできます。
この削減はかなり具体的ですが、これが便利になる状況が想像できます。
...
パラメータとして(varags)場合によっては、パラメータとしてJavaの可変引数を使用する方が、緩やかなものの代わりに短いことがあります。
例えば:
// Example input/output: 5, 4, 3 -> 60000
int calculateVolumeInLiters(int width, int height, int depth){
return width * height * depth * 1000;
}
ほとんどの人がこれにゴルフをするでしょう:
int c(int w,int h,int d){return w*h*d*1000;} // 44 bytes
しかし、これに追加のバイトをゴルフすることができます:
int c(int...a){return a[0]*a[1]*a[2]*1000;} // 43 bytes
3つの整数はすべて、メソッド自体で1回しかアクセスされないことに注意してください。以来int
、かなり短いですあなたはメソッド内で一度だけそれらそれぞれを使用し、パラメータとしてそれらの3以上を持っている場合にのみ有益です。
長いパラメーターでは、これは通常より便利です。たとえば、これはこのチャレンジに対する最初の答えでした(入力文字列の入力文字の出現を計算します):
// Example input/output: tttggloyoi, t -> 3
int c(String a,char b){return a.replaceAll("[^"+b+"]","").length();} // 68 bytes
そして、私はこれにゴルフすることを勧められました:
int c(String a,char b){return a.split(b+"").length-1;} // 54 bytes
しかし、私はこれを使ってこれにゴルフをしました...
:
int c(String...a){return a[0].split(a[1]).length-1;} // 52 bytes
注:質問/チャレンジが柔軟な入力を要求する場合、もちろん...
短縮できます[]
。質問/チャレンジが特に3つのString
入力を要求し、String
3つの値を含む-arrayを許可しない場合、のString...
代わりに使用できますString a,String b,String c
。
String[]
可変引数を使用する代わりにを使用することはできませんか?(さらに1バイトを保存)
package
スキップできます。