使用算术表达式表示给定大整数的策略


13

我有一个特定的数字,但这是我正在面临的挑战的一部分,并且我不希望人们为我做(所有)工作。

这是一个具有相同数字但乱序的数字:

5713167915926167134578399473447223554460066674314639815391281352328315313091488448321843
8892917486601064146636679920143691047671721184150386045081532202458651561779976236919751
5521854951599379666116678853267398393892536121049731949764192014193648608210652358947001
6332620900065461061195026191178967128001712341637591690941978871368243245270800684616029
6679555942849366434586090627998161441134473428845367022486230724219981658438108844675033
4461550796750244527407413996606134735852639191026103378962082622204359677030054592798927
4145951979523473408718011778751084514127053772614511042703365596651912104541233491744530
87457854312602843967491787086250478422477028164189

该数字有666位数字(十进制)。因为我使用的是Python,所以整数(或从技术上讲是long)会自动为bignums。

我有255个字符,需要描述相同的数字。该描述旨在通过eval()运行以产生原始编号。

我应该考虑什么策略?


base64(或更高版本)编码
Luis Mendo,2016年

2
您确定挑战中的实际数字没有某种属性,可以更轻松地压缩由于改组而丢失的数据吗?我认为路易斯的建议不会削减。即使以256为底,该数字仍然为277位。当然,您说您有“ 255个字符”,所以我想原则上您可以使用更大的基数,例如2 ^ 16,并使用Unicode。
马丁·恩德

4
这是要求产生代码的最短代码,绝对是在打高尔夫球。我担心的是来源不可信-如有可能,应将挑战联系在一起,以便我们归因并可以确定是否可以提供外部帮助。
xnor

我有255个字符,需要描述相同的数字。该描述旨在通过eval()运行以产生原始数字:从外部资源(例如网页)读取数字是否可以接受?
路易斯·门多

@LuisMendo不,它必须是自包含的。此外,它只能使用文件名中合法的字符。
Christian Sonne

Answers:


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 '16


1
以2²⁰为基数的数字仅145个字符
丹尼斯

4

素因数分解

如果数字没有有趣的功能,则基本编码是最好的方法。接下来要做的是寻找数字的有趣特征。首先想到的是,它可能具有将小素数(2、3、5、7等)提升为相当大的幂的因子。如果没有其他事情可做,请继续尝试除以小的素数,看看会发生什么。如果它的因素包括2**4,,3**47**4,则可以写big number *42**4比以下短几个字节的字节big number * 3111696


4
我还尝试将正负小数分解为整数,以查看其中一个是否具有更好的分解系数。另外,如果您的语言获取n素数的方法很短,则可以通过存储其索引(而不是素数本身)来为每个素数节省一位左右。
2012rcampion '16

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

通过平均几乎达到收支平衡,该算法非常适合与其他算法(甚至是自身)结合使用,以进一步减少表达式中的数字(以一些括号为代价)。这些其他算法可能会更昂贵,因为它们将以比原始算法少得多的数字进行运算。在给定的示例中,如果使用更昂贵,更有效的算法可以消除25%的字符33300095205899066129442737321270515378501483166974896029394675779096351509514355500527819871697116193238261137790928953798777695127752032484956608505929119246433389165(结果中的第二大值),则可以获得纯收益。


通过检查多维数据集可以稍微改善此方法,并且很少检查四次方。
Sparr

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上限增加一点)将发现659位数字也是N ~= 165661162**81.0000000025如此N-165661162**81,将要处理的数字减少7位,但需要花费14个字符的表达, 失败。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.