Strategi untuk mewakili bilangan bulat besar yang diberikan menggunakan ekspresi aritmatika

13

Saya memiliki angka tertentu dalam pikiran, tetapi ini adalah bagian dari tantangan yang saya lakukan, dan saya tidak ingin orang melakukan (semua) pekerjaan untuk saya.

Berikut adalah angka yang memiliki angka yang sama, tetapi dikocok:

5713167915926167134578399473447223554460066674314639815391281352328315313091488448321843
8892917486601064146636679920143691047671721184150386045081532202458651561779976236919751
5521854951599379666116678853267398393892536121049731949764192014193648608210652358947001
6332620900065461061195026191178967128001712341637591690941978871368243245270800684616029
6679555942849366434586090627998161441134473428845367022486230724219981658438108844675033
4461550796750244527407413996606134735852639191026103378962082622204359677030054592798927
4145951979523473408718011778751084514127053772614511042703365596651912104541233491744530
87457854312602843967491787086250478422477028164189

Angka tersebut memiliki 666 digit (desimal). Karena saya menggunakan Python, bilangan bulat (atau secara teknis rindu) secara otomatis bignum.

Saya memiliki 255 karakter untuk digunakan, dan saya perlu menjelaskan nomor yang sama. Deskripsi ini dimaksudkan untuk dijalankan melalui eval () untuk menghasilkan nomor asli.

Strategi apa yang harus saya perhatikan?

Christian Sonne
sumber
pengkodean base64 (atau lebih tinggi)
Luis Mendo
2
Apakah Anda yakin jumlah aktual dari tantangan Anda tidak memiliki properti yang membuatnya lebih mudah untuk dikompresi yang mungkin hilang karena perombakan? Saya tidak berpikir saran Luis akan memotongnya. Bahkan di basis 256, ini masih memiliki 277 digit. Tentu saja Anda bilang Anda punya "255 karakter", jadi saya kira pada prinsipnya Anda bisa menggunakan basis yang jauh lebih besar seperti 2 ^ 16, dan masuk ke Unicode.
Martin Ender
4
Ini meminta kode terpendek untuk menghasilkan angka, yang mutlak meminta saran golf. Kekhawatiran saya adalah sumbernya tidak terakreditasi - tantangannya harus dikaitkan jika memungkinkan sehingga kami memiliki atribusi dan dapat memeriksa apakah boleh memberikan bantuan dari luar.
xnor
Saya memiliki 255 karakter untuk digunakan, dan saya perlu menjelaskan nomor yang sama. Deskripsi dimaksudkan untuk dijalankan melalui eval () untuk menghasilkan nomor asli : apakah Anda dapat membaca nomor dari sumber daya eksternal, seperti halaman web?
Luis Mendo
@LuisMendo Tidak, itu harus lengkap. Selain itu, itu hanya dapat menggunakan karakter yang legal dalam nama file.
Christian Sonne

Jawaban:

12

Pengodean Basis

Teknik standar untuk mengompresi angka adalah mengekspresikannya dalam basis besar dan menyandikan digit sebagai karakter. Misalnya, jika Anda menyandikan angka dalam basis 256, itu hanya akan memiliki 277 digit:

[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]

Atau dinyatakan sebagai string

"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;]"

(Ditambah beberapa karakter yang tidak patut dicetak yang dilucuti oleh SE.)

Tentu saja, itu masih terlalu lama untuk tunjangan 255 karakter Anda. Jika Anda benar-benar berbicara tentang karakter (dibandingkan dengan byte), Anda dapat masuk ke Unicode dan menggunakan basis yang jauh lebih besar. Bagaimana dengan 2 16 ? Itu hanya 139 digit:

[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]

(Saya tidak dapat memasukkan string aktual di sini, karena berisi beberapa karakter CJK yang dilarang oleh SE.)

Sekarang sepertinya lebih bisa dilakukan. Anda hanya perlu mendekodekannya dalam 116 karakter. Jika tidak bisa, Unicode memiliki lebih dari 2 16 karakter, jadi Anda bisa mencoba menggunakan basis yang lebih besar.

Martin Ender
sumber
2
"Karakter CJK yang dilarang oleh SE" - wtf?
user253751
1
Basis 2²⁰ menggambarkan angka hanya dalam 145 karakter .
Dennis
4

Faktorisasi Perdana

Jika nomor tersebut tidak memiliki fitur yang menarik, pengkodean basis adalah cara terbaik untuk melakukannya. Hal selanjutnya yang harus dilakukan adalah mencari fitur menarik dari nomor tersebut. Yang pertama terlintas dalam pikiran adalah bahwa ia mungkin memiliki faktor bilangan prima kecil (2,3,5,7, dll) dinaikkan ke kekuatan yang cukup besar. JIKA Anda tidak memiliki hal lain untuk dilanjutkan, teruslah berusaha untuk membagi dengan bilangan prima kecil dan lihat apa yang terjadi. Jika faktor-faktornya meliputi 2**4,, 3**4dan 7**4, Anda dapat menulis big number *42**4yang beberapa byte lebih pendek daribig number * 3111696

Level River St
sumber
4
Saya juga akan mencoba memfaktorkan bilangan bulat plus atau minus kecil untuk melihat apakah salah satu dari mereka memiliki faktorisasi yang lebih baik. Juga, jika bahasa Anda memiliki cara singkat untuk mendapatkan nperdana, Anda dapat menyimpan satu atau dua digit per perdana dengan menyimpan indeksnya alih-alih perdana itu sendiri.
Arcampion
4

Penghapusan rekursif persegi terbesar

Pendekatan ini menghapus angka kuadrat terbesar dari N, berulang kali, hingga tidak ada nilai untuk melanjutkan.

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

Jika Anda mengabaikan karakter "** 2 +", yang ini rata-rata sekitar angka yang sama dengan angka aslinya, rata-rata. Mengganti 4 karakter ekstra per iterasi membutuhkan sedikit keberuntungan. Dalam hal nomor Anda, hasilnya memiliki 670 digit angka kuadrat, ditambah 7x "** 2+", kegagalan lain:

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

Dengan hampir mencapai titik impas rata-rata, algoritma ini cocok untuk digunakan bersama dengan algoritma lain (atau bahkan sendiri) untuk lebih mengurangi angka dalam ekspresi (dengan biaya beberapa tanda kurung). Algoritme lain itu bisa lebih mahal, karena akan beroperasi pada angka yang jauh lebih kecil daripada yang asli. Dalam contoh yang diberikan, keuntungan bersih dapat diperoleh jika algoritma yang lebih mahal dan efektif dapat memotong 25% karakter 33300095205899066129442737321270515378501483166974896029394675779096351509514355500527819871697116193238261137790928953798777695127752032484956608505929119246433389165(nilai besar kedua dalam hasil)

Sparr
sumber
Pendekatan ini dapat sedikit ditingkatkan dengan memeriksa kubus, dan sangat jarang kekuatan keempat, juga.
Sparr
0

Kekuatan besar terdekat

Pendekatan ini mencari [relatif] angka kecil yang dinaikkan ke sejumlah daya yang mendekati jumlah target. Dalam kebanyakan kasus menyatakan kembali N sebagai A ** B + C tidak akan menjadi perbaikan, tetapi dalam beberapa kasus itu akan menjadi perbaikan.

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

10000adalah konstanta arbitrer. Kondisi bail-out juga bisa didasarkan pada beberapa target mindiff.

Dalam hal jumlah sampel Anda N dengan 666 digit, fungsi ini (dengan tutup 10k sedikit meningkat) mendapati bahwa N ~= 165661162**81.0000000025, demikian N-165661162**81juga dengan angka 659 digit, memotong 7 digit dari angka yang akan ditangani dengan biaya 14 karakter ekspresi , sebuah kegagalan.

Sparr
sumber