算術式を使用して特定の大きな整数を表現するための戦略


13

特定の数を念頭に置いていますが、それは私がしている挑戦の一部です。

以下は、同じ数字ですがシャッフルされた数字です。

5713167915926167134578399473447223554460066674314639815391281352328315313091488448321843
8892917486601064146636679920143691047671721184150386045081532202458651561779976236919751
5521854951599379666116678853267398393892536121049731949764192014193648608210652358947001
6332620900065461061195026191178967128001712341637591690941978871368243245270800684616029
6679555942849366434586090627998161441134473428845367022486230724219981658438108844675033
4461550796750244527407413996606134735852639191026103378962082622204359677030054592798927
4145951979523473408718011778751084514127053772614511042703365596651912104541233491744530
87457854312602843967491787086250478422477028164189

数字は666桁(10進数)です。Pythonを使用しているため、整数(または技術的に長い)は自動的にbignumです。

使用する255文字があり、同じ番号を記述する必要があります。説明は、元の数値を生成するためにeval()を実行することを意図しています。

どの戦略を検討すべきですか?


base64(またはそれ以上)エンコーディング
ルイスメンドー

2
チャレンジからの実際の数値には、シャッフルによって失われる可能性のある圧縮を容易にするいくつかのプロパティがありませんか?ルイスの提案がそれを減らすとは思わない。ベース256でも、これはまだ277桁です。もちろん「255文字」だと言っていたので、原則として2 ^ 16のようなはるかに大きなベースを使用して、Unicodeに移行できると思います。
マーティンエンダー

4
これは、数字を生成するための最短のコードを要求しています。これは絶対にゴルフのアドバイスを求めています。私の懸念は、ソースが信用されていないことです-可能な場合は課題をリンクする必要がありますので、帰属があり、外部の助けを与えることを確認できます。
xnor

使用する255文字があり、同じ番号を記述する必要があります。説明は、eval()を実行して元の番号を生成することを目的としています。Webページなどの外部リソースから番号を読み取ることは受け入れられますか?
ルイスメンドー

@LuisMendoいいえ、自己完結型でなければなりません。また、ファイル名で有効な文字のみを使用できます。
クリスチャンソンヌ

回答:


12

ベースエンコーディング

数字を圧縮するための標準的な手法は、数字を大きなベースで表現し、数字を文字としてエンコードすることです。たとえば、数値を基数256でエンコードすると、277桁のみになります。

[12 24 156 48 101 149 235 32 96 92 20 203 202 164 144 71 193 127 112 77 141 79 210 183 98 155 16 151 65 198 26 236 83 221 220 129 169 254 43 124 245 25 176 182 167 124 95 191 77 25 233 139 190 7 135 2 149 90 163 163 106 193 220 253 109 129 57 219 91 157 218 18 223 11 171 113 209 173 207 123 110 220 79 139 176 143 171 7 30 35 231 151 172 83 120 114 119 47 217 227 50 105 236 91 161 226 112 16 170 57 162 147 36 89 26 9 122 164 15 15 243 108 30 14 233 139 103 137 82 169 2 57 54 71 154 136 23 203 137 10 219 153 24 168 42 218 165 125 185 183 241 91 193 85 195 71 186 18 98 34 196 78 6 193 252 8 177 94 5 24 137 183 127 129 9 77 149 73 148 193 62 220 146 33 130 21 209 153 229 105 100 188 87 235 203 104 207 161 20 17 102 150 252 120 242 222 233 248 114 217 142 31 196 42 161 173 0 244 9 213 178 152 122 170 136 230 135 132 245 69 9 196 231 147 8 175 48 98 101 23 162 144 190 200 62 226 61 27 200 15 232 12 105 187 184 4 121 252 171 240 230 94 161 151 131 209 205 130 193 9 4 155 92 48 59 130 93]

または文字列として表現されます

"0eë `\ËʤGÁpMOÒ·bAÆìSÝÜ©þ+|õ°¶§|_¿Mé¾Z££jÁÜým9Û[Úß«qÑ­Ï{nÜO°«#ç¬Sxrw/Ùã2iì[¡âpª9¢$Y  z¤ólégR©96GË
Û¨*Ú¥}¹·ñ[ÁUÃGºb\"ÄNÁü±^· MIÁ>Ü!Ñåid¼WëËhÏ¡füxòÞéørÙÄ*¡­ô  Õ²zªæõE Äç¯0be¢¾È>â=Èèi»¸yü«ðæ^¡ÑÍÁ  \0;]"

(さらに、SEによって削除される印刷できない文字もあります。)

もちろん、それは255文字の許容量にはまだ長すぎます。(バイトではなく)実際に文字について話している場合は、Unicodeを使用してはるかに大きなベースを使用できます。2 16はどうですか?それはわずか139桁です。

[12 6300 12389 38379 8288 23572 52170 42128 18369 32624 19853 20434 46946 39696 38721 50714 60499 56796 33193 65067 31989 6576 46759 31839 48973 6633 35774 1927 661 23203 41834 49628 64877 33081 56155 40410 4831 2987 29137 44495 31598 56399 35760 36779 1822 9191 38828 21368 29303 12249 58162 27116 23457 57968 4266 14754 37668 22810 2426 41999 4083 27678 3817 35687 35154 43266 14646 18330 34839 52105 2779 39192 43050 55973 32185 47089 23489 21955 18362 4706 8900 19974 49660 2225 24069 6281 46975 33033 19861 18836 49470 56466 8578 5585 39397 26980 48215 60363 26831 41236 4454 38652 30962 57065 63602 55694 8132 10913 44288 62473 54706 39034 43656 59015 34037 17673 50407 37640 44848 25189 6050 37054 51262 57917 7112 4072 3177 48056 1145 64683 61670 24225 38787 53709 33473 2308 39772 12347 33373]

(SEによって禁止されているCJK文字が含まれているため、実際の文字列をここに含めることはできません。)

今では、より実行可能に思えます。116文字でデコードできる必要があります。できない場合、Unicodeには2 16文字をはるかに超える文字が含まれているため、さらに大きなベースを使用してみてください。


2
「SEによって禁止されているCJKキャラクター」-wtf?
user253751


1
基数2²⁰は、数字を145文字で説明します。
デニス

4

素因数分解

数値に興味深い機能がない場合は、ベースエンコーディングが最適な方法です。次にすべきことは、数字の興味深い特徴を探すことです。最初に思い浮かぶのは、小さな素数(2,3,5,7など)の因子が非常に大きな累乗に引き上げられる可能性があることです。続行するものが他にない場合は、小さな素数で割って何が起こるかを確認してください。その要因が含まれている場合2**43**4および7**4、あなたが書くことができるbig number *42**4よりも数バイト短くなりますbig number * 3111696


4
また、小さい整数のプラスまたはマイナスの数を因数分解して、そのうちの1つがより良い因数分解を持っているかどうかを確認します。また、言語にnth素数を取得する短い方法がある場合、素数自体の代わりにインデックスを保存することにより、素数ごとに数字などを保存できます。
-2012rcampion

4

最大の正方形の再帰的除去

このアプローチは、継続する価値がなくなるまで、Nから最大の平方数を繰り返し削除します。

while(n>999*999):
    s = sqrt(n,2)
    print s,"** 2 +"
    n = n - s**2
print n

「** 2 +」文字を無視すると、これは平均して元の数字とほぼ同じ桁数になります。反復ごとにこれら4つの余分な文字を補うには、少し運が必要です。番号の場合、結果には670桁の正方形の数値に加えて、7x "** 2+"の別の失敗があります。

755855006990505232214298076833020140623897728341856142793250050184099570268569900389346192358073922001480310798643405893673501405667458785677166605919485512157948819102093414848159820683798554799982163455753292781944741934237780592730586508786425528910736750640071037094033497266578109597923654387813828207885510302579581252831537751**2+
33300095205899066129442737321270515378501483166974896029394675779096351509514355500527819871697116193238261137790928953798777695127752032484956608505929119246433389165**2+
187763197402063683206154659623192450644818397963460986292088297442441704645626089130**2+
278760215056365252005927060531480627653626**2+
639191600506542558482**2+
25777519523**2+
106673**2+
103405

このアルゴリズムは、平均でほぼ均等になることにより、他のアルゴリズム(またはそれ自体)と組み合わせて使用​​して、式の数をさらに減らすことができます(括弧が必要です)。これらの他のアルゴリズムは、元のアルゴリズムよりも大幅に小さい数で動作するため、より高価になる可能性があります。与えられた例では、より高価で効果的なアルゴリズムが33300095205899066129442737321270515378501483166974896029394675779096351509514355500527819871697116193238261137790928953798777695127752032484956608505929119246433389165(結果の2番目に大きい値)の文字の25%を切り取ることができれば、正味の利益が得られます。


このアプローチは、キューブを確認することでわずかに改善できます。また、めったに4乗も確認できません。
スパー

0

近くの大国

このアプローチは、[比較的]目標数に近づいた、あるべき乗した小さな数を探します。ほとんどの場合、NをA ** B + Cとして再記述しても改善されませんが、場合によっては改善されます。

def nearest_power(n):
    mindiff = 1
    best = (n,1)
    for a in xrange(2,10000):
        b = math.log(n,a)
        if math.ceil(b)-b<mindiff:
            mindiff = math.ceil(b)-b
            print a,"**",b
            best = (a,b)
        if b-math.floor(b)<mindiff:
            mindiff = b-math.floor(b)
            print a,"**",b
            best = (a,b)
    return best

10000は任意の定数です。救済条件は、何らかのターゲットに基づいている場合もありますmindiff

666桁を使用して、サンプル数Nの場合には、この機能(10Kキャップとは、ビットの増加)ことを発見するN ~= 165661162**81.0000000025ように、N-165661162**81発現の14文字のコストで処理する番号オフ7桁を切断、659桁の数であります、 失敗。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.