ゴルフ中に、コードで多数の数字を表す必要がある場合があります。そのまま書き込むと、バイト数が大幅に増加する可能性があります。
長い数字をコードで簡潔に表現するための一般的な1つのヒントは何ですか?
回答ごとに1つのヒントを投稿してください。
1で一般的には、私は、単一の言語以上に適用することができヒントを意味します。言語固有のヒントについては、それぞれのスレッドに投稿してください。
ゴルフ中に、コードで多数の数字を表す必要がある場合があります。そのまま書き込むと、バイト数が大幅に増加する可能性があります。
長い数字をコードで簡潔に表現するための一般的な1つのヒントは何ですか?
回答ごとに1つのヒントを投稿してください。
1で一般的には、私は、単一の言語以上に適用することができヒントを意味します。言語固有のヒントについては、それぞれのスレッドに投稿してください。
回答:
一部の言語には、平方、2を底とする累乗、n番目の素数、階乗、または大きな数を生成できるその他の手続きの組み込み関数があります。番号がこれらのカテゴリのいずれかに該当するかどうかを確認してください。
一致しない場合は、目的に合ったより大きな数を使用して、代わりに使用できる可能性があります。
1.01e6
反復が十分であれば1e7
、実行時間を犠牲にして3バイトを節約します。
一部の言語には、ビット単位のAND、OR、XOR、および時にはNOTがあります。
特定の大きな数値を、べき乗または左シフトの結果と別の数値のビットごとの組み合わせとして表現すると、必要な数値を正確に得ることができます。これは通常、数値が非常に大きくなった場合にのみ価値があります。
たとえば、2147483722
は10バイトですが、2<<30^74
(2 ^ 31ビット単位のXORと74)は8のみです。
bc
)、シフト演算子はべき乗に置き換えることができます。そして、XORは+
and よりも有用ではありません-
:この場合、xorとaddは同じ結果を与えますが、すべての場合、整数を持つxorと同じ結果を生成するために加算または減算できる整数があり、加数は大きくなく、時には短くなりません。
1e9^2e9
。
9<<49^7<<19
xorの代わりに加算を使用してどのように表現しますか?
1286561280
JavaScriptおよびPerl(およびおそらく他の言語)で評価され、+
またはを使用した同等の値よりもその値を生成するための短い式-
です。
本質的に非常に反復的な数値の場合、文字列を使用して整数にキャストできます。たとえば、JavaScriptで
+"1".repeat(100) // returns 100 1s (saves 84 bytes!)
1e100/9
、この場合、非常に大きな割合を使用できます。
これは無回答のように聞こえるかもしれませんが、短いコードでより大きな数を計算できることは必ずしも明らかではありません。私が覚えている例は、明らかな答えが10 100の計算を必要とする、文字列のgoogolコピーの出力です。結局のところ、10 100の倍数を計算すると、同じように正確になりますが、一部の言語では短い答えになります。そこでのデニスの答えは100 100を使用し、私自身は250 255を使用します。
es
必要な数が多いだけで、その値を気にしない(または常に同じである)場合に現在のタイムスタンプを取得できます。
ベース解凍コードはかなり複雑になる可能性がありますが、本当に膨大な数がある場合は、10を超えるベースで圧縮すると役立つ場合があります。
また、一部の言語では、基本圧縮コードが非常に単純であることも役立ちます。たとえば、PHPにはbase64_decode(_)
、Pythonにはint(_,36)
、JavaScriptにはがparseInt(_,36)
あり、多くのゴルフ言語には基本的な圧縮解除ビルトインがあります。たとえば、CJamの場合:
"+ÜTbô±"256b
これには印刷できないものが含まれています。オンラインでお試しください!
これにより以下が得られます。
12345678987654321
100個の1で構成される数を生成するとします。、などを使用できますがint("1"*100)
、+"1".repeat(100)
非常に近いという事実を利用することもできます
1e100/9
これは、1桁の数字など、非常に反復的な数字に最適です。繰り返される数字もいくつかうまくいきます:
12e100/99 // Generates 121212121212... (100 digits)
時折、このメソッドでかなり簡潔に表現できる他の奇妙なパターンを見つけることがあります。が必要になった場合int("123456790"*11)
、たとえば:
1e100/81
しかし、注意してください:などの数字int("1234567890"*10)
は、そのような簡単な表現を持っていません。
べき乗演算子をサポートする言語はたくさんありますが、そうでない言語もあります。そして、そうでないものは、通常、関数(またはクラス/オブジェクトメソッド)を呼び出す必要があり、数バイトかかることがあります。
ただし、ビット単位の左シフト演算子をとして使用することにより、2のn乗する必要がある場合、いくつかのバイトを節約できます。これは、nが17以上の場合にのみバイトを節約することに注意してください。ただし、nが動的の場合、常にバイトを節約します。いくつかの例:<<
1<<n
1<<2 // returns 4 (3 bytes more :( )
1<<3 // returns 8 (3 bytes more :( )
1<<6 // returns 64 (2 bytes more :( )
1<<14 // returns 16384 (no bytes saved)
1<<17 // returns 131072 (saves 1 byte!)
1<<18 // returns 262114 (saves 1 byte!)
8<<9 // 4096
したがって、最大99<<61
6バイトで取得できます。 これは6,917,529,027,641,081,856
13バイトの節約に相当します。
任意の大きな整数が頻繁に表示される場合、またはターゲットプログラミング言語での大きな整数表現のバイト数が多すぎる場合は、中国剰余定理の使用を検討できます。
ペアの比較的素数の整数m i > = 2を選択すると、0〜lcm(m 1、m 2、...、m i)-1の大きな数を表現できます。
たとえば、2、3、5、11、79、83、89、97を選択すると、18680171730未満の数値を一意に表現できます。10000000000(1e10)は0,1,0,1,38,59,50,49(1e10 mod 2、3 ...、97)として表現できます。いくつかのプログラミング言語のいくつかのバイト。
この表現を使用して、加算と減算を直接行うことができます。例:
(0,1,0,1,38,59,50,49)+(0,2,0,6,23,20,16,53) = 1e10 + 5000
= (0+0 mod 2, 1+2 mod 3, 0+0 mod 5, 1+6 mod 11, 38+23 mod 79, 59+20 mod 83, 50+16 mod 89, 49+53 mod 97)
言語に指数演算子がある場合は、それを使用して、必要な数ではないにしても、少なくとも簡単な計算を実行できる数、または2を使用して数に到達することができます。演算子がなくても、組み込みの関数またはメソッドでバイトを保存できる場合があります。
JavaScriptで最大安全の整数である9007199254740991
16桁の長さです。ES7では、これは次の7バイトで計算できます。
2**53-1
ES6以前の同等物は、このインスタンスの整数自体と同じ長さですが、より冗長な方法を使用しても必ずしもバイトがかかるとは限らないことを示しています。
Math.pow(2,53)-1
ただし、たとえば、コード内の別の場所で1つの文字のエイリアスを既に作成している場合、上記の方法は短くなる場合Math
があります。