J'ai un numéro précis en tête, mais cela fait partie d'un défi que je fais et je ne veux pas que les gens fassent (tout) le travail pour moi.
Voici un nombre qui a les mêmes chiffres, mais mélangé:
5713167915926167134578399473447223554460066674314639815391281352328315313091488448321843
8892917486601064146636679920143691047671721184150386045081532202458651561779976236919751
5521854951599379666116678853267398393892536121049731949764192014193648608210652358947001
6332620900065461061195026191178967128001712341637591690941978871368243245270800684616029
6679555942849366434586090627998161441134473428845367022486230724219981658438108844675033
4461550796750244527407413996606134735852639191026103378962082622204359677030054592798927
4145951979523473408718011778751084514127053772614511042703365596651912104541233491744530
87457854312602843967491787086250478422477028164189
Le nombre comprend 666 chiffres (décimal). Parce que j'utilise Python, les entiers (ou techniquement longs) sont automatiquement des bignums.
J'ai 255 caractères à utiliser et je dois décrire le même nombre. La description doit être exécutée via eval () pour produire le numéro d'origine.
Quelles stratégies dois-je envisager?
code-golf
kolmogorov-complexity
tips
python
compression
Christian Sonne
la source
la source
Réponses:
Encodage de base
Une technique standard de compression des nombres consiste à les exprimer dans une grande base et à coder les chiffres sous forme de caractères. Par exemple, si vous encodez le nombre en base 256, il n'aura que 277 chiffres:
Ou exprimé sous forme de chaîne
(Plus quelques caractères non imprimables qui sont supprimés par SE.)
Bien sûr, c'est encore trop long pour votre allocation de 255 caractères. Si vous parlez en fait de caractères (par opposition aux octets), vous pouvez aller dans Unicode et utiliser une base beaucoup plus grande. Que diriez-vous de 2 16 ? Cela ne fait que 139 chiffres:
(Je ne peux pas inclure la chaîne réelle ici, car elle contient des caractères CJK qui sont interdits par SE.)
Maintenant, cela semble plus faisable. Il vous suffit de pouvoir le décoder en 116 caractères. Si vous ne le pouvez pas, Unicode a beaucoup plus de 2 16 caractères, vous pouvez donc essayer d'utiliser une base encore plus grande.
la source
Factorisation principale
Si le nombre n'a pas de fonctionnalités intéressantes, l'encodage de base est le meilleur moyen de le faire. La prochaine chose à faire est de rechercher des caractéristiques intéressantes du numéro. Le premier qui me vient à l'esprit est qu'il peut avoir des facteurs de petits nombres premiers (2,3,5,7, etc.) élevés à des puissances assez importantes. SI vous n'avez rien d'autre à faire, essayez de diviser par petits nombres premiers et voyez ce qui se passe. Si ses facteurs comprennent
2**4
,3**4
et7**4
, vous pouvez écrire cebig number *42**4
qui est quelques octets plus courte quebig number * 3111696
la source
n
e premier, vous pouvez enregistrer un chiffre ou plus par premier en stockant son index au lieu du premier lui-même.Suppression récursive du plus grand carré
Cette approche supprime le plus grand nombre carré de N, à plusieurs reprises, jusqu'à ce qu'il n'y ait aucune valeur à continuer.
Si vous ignorez les caractères "** 2 +", celui-ci donne approximativement le même nombre de chiffres que le numéro d'origine, en moyenne. Pour compenser ces 4 caractères supplémentaires par itération, il faut un peu de chance. Dans le cas de votre numéro, le résultat a 670 chiffres de nombres carrés, plus 7x "** 2+", un autre échec:
En atteignant presque le seuil de rentabilité en moyenne, cet algorithme se prête bien à être utilisé en conjonction avec d'autres algorithmes (ou même lui-même) pour réduire davantage les nombres dans l'expression (au prix de certaines parenthèses). Ces autres algorithmes peuvent être plus chers, car ils fonctionneront sur des nombres beaucoup plus petits que l'original. Dans l'exemple donné, un gain net pourrait être obtenu si un algorithme plus coûteux et efficace pouvait supprimer 25% des caractères de
33300095205899066129442737321270515378501483166974896029394675779096351509514355500527819871697116193238261137790928953798777695127752032484956608505929119246433389165
(la deuxième grande valeur du résultat)la source
Grandes puissances à proximité
Cette approche recherche des nombres [relativement] petits élevés à une puissance proche du nombre cible. Dans la plupart des cas, reformuler N en A ** B + C ne sera pas une amélioration, mais dans certains cas, elle le sera.
10000
est une constante arbitraire. La condition de renflouement pourrait également être basée sur un objectifmindiff
.Dans le cas de votre numéro d'échantillon N avec 666 chiffres, cette fonction (avec la limite de 10k augmentée un peu) constate que
N ~= 165661162**81.0000000025
, toutN-165661162**81
comme un nombre de 659 chiffres, couper 7 chiffres du nombre à traiter au coût de 14 caractères d'expression , un échec.la source