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?
code-golf
kolmogorov-complexity
tips
python
compression
Christian Sonne
quelle
quelle
Antworten:
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:
Oder als Zeichenfolge ausgedrückt
(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:
(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.
quelle
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**4
und7**4
können Sie schreiben ,big number *42**4
die ein paar Bytes kürzer alsbig number * 3111696
quelle
n
th-Primzahl zu erhalten, können Sie eine Ziffer pro Primzahl speichern, indem Sie den Index anstelle der Primzahl selbst speichern.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.
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:
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.quelle
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.
10000
ist eine beliebige Konstante. Die Rettungsbedingung könnte auch auf einem bestimmten Ziel beruhenmindiff
.Im Fall Ihrer Stichprobennummer N mit 666 Stellen stellt diese Funktion (mit der 10k-Obergrenze etwas erhöht) fest
N ~= 165661162**81.0000000025
, dassN-165661162**81
es sich bei einer 659-stelligen Nummer um eine 7-stellige Kürzung der zu bearbeitenden Zahl handelt, was 14 Zeichen Ausdruck kostet , ein Fehler.quelle