Strategien zur Darstellung einer bestimmten großen Ganzzahl unter Verwendung eines arithmetischen Ausdrucks


13

Ich habe eine bestimmte Nummer im Sinn, aber es ist Teil einer Herausforderung, die ich mache, und ich möchte nicht, dass die Leute die Arbeit für mich erledigen.

Hier ist eine Zahl mit den gleichen Ziffern, aber gemischt:

5713167915926167134578399473447223554460066674314639815391281352328315313091488448321843
8892917486601064146636679920143691047671721184150386045081532202458651561779976236919751
5521854951599379666116678853267398393892536121049731949764192014193648608210652358947001
6332620900065461061195026191178967128001712341637591690941978871368243245270800684616029
6679555942849366434586090627998161441134473428845367022486230724219981658438108844675033
4461550796750244527407413996606134735852639191026103378962082622204359677030054592798927
4145951979523473408718011778751084514127053772614511042703365596651912104541233491744530
87457854312602843967491787086250478422477028164189

Die Nummer hat 666 Stellen (dezimal). Da ich Python verwende, sind Ganzzahlen (oder technisch gesehen Longs) automatisch Bignums.

Ich habe 255 Zeichen zu verwenden, und ich muss die gleiche Nummer beschreiben. Die Beschreibung soll eval () durchlaufen, um die ursprüngliche Nummer zu erhalten.

Welche Strategien sollte ich prüfen?


base64-Codierung (oder höher)
Luis Mendo

2
Sind Sie sicher, dass die tatsächliche Zahl aus Ihrer Challenge keine Eigenschaft hat, die das Komprimieren erleichtert, die durch das erneute Mischen verloren gehen kann? Ich glaube nicht, dass Luis Vorschläge das ändern werden. Selbst in der Basis 256 hat dies noch 277 Stellen. Natürlich sagten Sie, Sie hätten "255 Zeichen", also könnten Sie im Prinzip eine viel größere Basis wie 2 ^ 16 verwenden und in Unicode einsteigen.
Martin Ender

4
Dies verlangt nach dem kürzesten Code, um eine Zahl zu erzeugen, und bittet unbedingt um Golfratschläge. Ich mache mir Sorgen, dass die Quelle nicht im Abspann aufgeführt ist - die Herausforderung sollte nach Möglichkeit verknüpft sein, damit wir Zuschreibungen haben und prüfen können, ob es in Ordnung ist, Hilfe von außen zu leisten.
Xnor

Ich habe 255 Zeichen zu verwenden, und ich muss die gleiche Nummer beschreiben. Die Beschreibung soll eval () durchlaufen, um die ursprüngliche Nummer zu erhalten. Ist es für Sie akzeptabel, die Nummer aus einer externen Ressource wie einer Webseite zu lesen?
Luis Mendo

@ LuisMendo Nein, es muss in sich geschlossen sein. Außerdem können nur Zeichen verwendet werden, die in einem Dateinamen zulässig sind.
Christian Sonne

Antworten:


12

Basiscodierung

Eine Standardtechnik zum Komprimieren von Zahlen besteht darin, sie in einer großen Basis auszudrücken und die Ziffern als Zeichen zu codieren. Wenn Sie beispielsweise die Zahl in Basis 256 codieren, hat sie nur 277 Ziffern:

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

Oder als Zeichenfolge ausgedrückt

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

(Plus einige nicht druckbare Zeichen, die von SE entfernt werden.)

Das ist natürlich immer noch zu lang für Ihre 255 Zeichen. Wenn Sie jedoch tatsächlich über Zeichen sprechen (im Gegensatz zu Bytes), können Sie Unicode verwenden und eine viel größere Basis verwenden. Wie wäre es mit 2 16 ? Das sind nur 139 Stellen:

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

(Ich kann die tatsächliche Zeichenfolge hier nicht einfügen, da sie einige von SE gesperrte CJK-Zeichen enthält.)

Das scheint machbarer zu sein. Sie müssen es nur in 116 Zeichen dekodieren können. Wenn dies nicht möglich ist, enthält Unicode mehr als 2 bis 16 Zeichen. Sie können also versuchen, eine noch größere Basis zu verwenden.


2
"CJK-Zeichen, die von SE gebannt werden" - wtf?
user253751


1
Basis 2²⁰ beschreibt die Zahl in nur 145 Zeichen .
Dennis

4

Prime Factorization

Wenn die Zahl keine interessanten Merkmale aufweist, ist die Basiscodierung der beste Weg, dies zu tun. Als nächstes müssen Sie nach interessanten Merkmalen der Nummer suchen. Das erste, was mir in den Sinn kommt, ist, dass es Faktoren mit kleinen Primzahlen (2,3,5,7 usw.) geben kann, die auf ziemlich große Potenzen angehoben werden. WENN Sie nichts weiter zu tun haben, versuchen Sie immer wieder, sich durch kleine Primzahlen zu teilen und zu sehen, was passiert. Wenn seine Faktoren umfassen 2**4, 3**4und 7**4können Sie schreiben , big number *42**4die ein paar Bytes kürzer alsbig number * 3111696


4
Ich würde auch versuchen, die Zahl plus oder minus kleiner Ganzzahlen zu faktorisieren, um zu sehen, ob eine von ihnen eine schönere Faktorisierung hat. Wenn Ihre Sprache einen kurzen Weg hat, um die nth-Primzahl zu erhalten, können Sie eine Ziffer pro Primzahl speichern, indem Sie den Index anstelle der Primzahl selbst speichern.
2012rcampion

4

Rekursives Entfernen des größten Quadrats

Bei diesem Ansatz wird die größte Quadratzahl wiederholt aus N entfernt, bis es keinen Wert mehr gibt, fortzufahren.

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

Wenn Sie die Zeichen "** 2 +" ignorieren, entspricht diese im Durchschnitt ungefähr der Anzahl der Ziffern der ursprünglichen Zahl. Um diese 4 zusätzlichen Zeichen pro Iteration auszugleichen, ist ein wenig Glück erforderlich. Im Fall Ihrer Nummer hat das Ergebnis 670 Stellen mit quadratischen Zahlen plus 7x "** 2+", ein weiterer Fehler:

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

Da dieser Algorithmus im Durchschnitt fast ausgeglichen ist, eignet er sich gut für die Verwendung in Verbindung mit anderen Algorithmen (oder sogar für sich selbst), um die Zahlen im Ausdruck weiter zu reduzieren (auf Kosten einiger Klammern). Diese anderen Algorithmen können teurer sein, da sie mit einer erheblich geringeren Anzahl arbeiten als das Original. In dem gegebenen Beispiel könnte ein Nettogewinn erzielt werden, wenn ein teurerer und effektiverer Algorithmus 25% der Zeichen von 33300095205899066129442737321270515378501483166974896029394675779096351509514355500527819871697116193238261137790928953798777695127752032484956608505929119246433389165(dem zweiten großen Wert im Ergebnis) herausschneiden könnte.


Dieser Ansatz kann leicht verbessert werden, indem nach Würfeln und sehr selten auch nach vierten Potenzen gesucht wird.
Sparr

0

In der Nähe große Kräfte

Dieser Ansatz sucht nach [relativ] kleinen Zahlen, die auf eine Potenz angehoben werden, die der Zielzahl nahekommt. In den meisten Fällen wird es keine Verbesserung sein, N als A ** B + C zu schreiben, in einigen Fällen jedoch.

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

10000ist eine beliebige Konstante. Die Rettungsbedingung könnte auch auf einem bestimmten Ziel beruhen mindiff.

Im Fall Ihrer Stichprobennummer N mit 666 Stellen stellt diese Funktion (mit der 10k-Obergrenze etwas erhöht) fest N ~= 165661162**81.0000000025, dass N-165661162**81es sich bei einer 659-stelligen Nummer um eine 7-stellige Kürzung der zu bearbeitenden Zahl handelt, was 14 Zeichen Ausdruck kostet , ein Fehler.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.