Tengo un número específico en mente, pero es parte de un desafío que estoy haciendo, y no quiero que la gente haga (todo) el trabajo por mí.
Aquí hay un número que tiene los mismos dígitos, pero barajado:
5713167915926167134578399473447223554460066674314639815391281352328315313091488448321843
8892917486601064146636679920143691047671721184150386045081532202458651561779976236919751
5521854951599379666116678853267398393892536121049731949764192014193648608210652358947001
6332620900065461061195026191178967128001712341637591690941978871368243245270800684616029
6679555942849366434586090627998161441134473428845367022486230724219981658438108844675033
4461550796750244527407413996606134735852639191026103378962082622204359677030054592798927
4145951979523473408718011778751084514127053772614511042703365596651912104541233491744530
87457854312602843967491787086250478422477028164189
El número tiene 666 dígitos (decimal). Como estoy usando Python, los enteros (o técnicamente largos) son automáticamente bignums.
Tengo 255 caracteres para usar, y necesito describir el mismo número. La descripción debe ejecutarse a través de eval () para producir el número original.
¿Qué estrategias debería estar estudiando?
code-golf
kolmogorov-complexity
tips
python
compression
Christian Sonne
fuente
fuente
Respuestas:
Codificación Base
Una técnica estándar para comprimir números es expresarlos en una gran base y codificar los dígitos como caracteres. Por ejemplo, si codifica el número en la base 256, tendría solo 277 dígitos:
O expresado como una cadena
(Además de algunos caracteres no imprimibles que SE eliminan).
Por supuesto, eso todavía es demasiado largo para tu asignación de 255 caracteres. Sin embargo, si en realidad estás hablando de caracteres (a diferencia de los bytes), puedes ingresar a Unicode y usar una base mucho más grande. ¿Qué tal 2 16 ? Eso es solo 139 dígitos:
(No puedo incluir la cadena real aquí, porque contiene algunos caracteres CJK que están prohibidos por SE).
Ahora eso parece más factible. Solo necesita poder decodificarlo en 116 caracteres. Si no puede, Unicode tiene más de 2 16 caracteres, por lo que podría intentar usar una base aún más grande.
fuente
Factorización Prime
Si el número no tiene características interesantes, la codificación base es la mejor manera de hacerlo. Lo siguiente que debe hacer es buscar características interesantes del número. Lo primero que viene a la mente es que puede tener factores de números primos pequeños (2,3,5,7, etc.) elevados a poderes bastante grandes. SI no tiene nada más que seguir, siga tratando de dividir entre pequeños números primos y vea qué sucede. Si sus factores incluyen
2**4
,3**4
y7**4
, puede escribirbig number *42**4
que es unos pocos bytes más corto quebig number * 3111696
fuente
n
primer primo, puede guardar aproximadamente un dígito por primo almacenando su índice en lugar del primo en sí.Remoción recursiva del cuadrado más grande
Este enfoque elimina el número cuadrado más grande de N, repetidamente, hasta que no haya ningún valor en continuar.
Si ignora los caracteres "** 2 +", este tiene aproximadamente el mismo número de dígitos que el número original, en promedio. Compensar esos 4 caracteres adicionales por iteración requiere un poco de suerte. En el caso de su número, el resultado tiene 670 dígitos de números cuadrados, más 7x "** 2+", otra falla:
Casi al punto de equilibrio, en promedio, este algoritmo se presta bien para ser utilizado junto con otros algoritmos (o incluso a sí mismo) para reducir aún más los números en la expresión (a costa de algunos paréntesis). Esos otros algoritmos pueden ser más caros, ya que operarán en números significativamente más pequeños que el original. En el ejemplo dado, se podría obtener una ganancia neta si un algoritmo más costoso y efectivo pudiera eliminar el 25% de los caracteres de
33300095205899066129442737321270515378501483166974896029394675779096351509514355500527819871697116193238261137790928953798777695127752032484956608505929119246433389165
(el segundo valor grande en el resultado)fuente
Grandes poderes cercanos
Este enfoque busca números [relativamente] pequeños elevados a una potencia que se acerque al número objetivo. En la mayoría de los casos, restablecer N como A ** B + C no será una mejora, pero en algunos casos lo será.
10000
Es una constante arbitraria. La condición de rescate también podría basarse en algún objetivomindiff
.En el caso de su número de muestra N con 666 dígitos, esta función (con el límite de 10k aumentado un poco) encuentra que
N ~= 165661162**81.0000000025
, al igualN-165661162**81
que un número de 659 dígitos, corta 7 dígitos del número que se manejará a un costo de 14 caracteres de expresión , un fracaso.fuente