Parfois, en jouant au golf, il faut représenter un ou plusieurs grands nombres dans leur code. Les écrire tels quels peut augmenter considérablement le nombre d'octets.
Qu'est - ce que le général 1 conseils avez - vous pour représenter les nombres longs de façon concise dans le code?
Veuillez poster un pourboire par réponse.
1 Avec générale , je veux dire des conseils qui peuvent être appliquées à plus d'une seule langue. Pour des conseils spécifiques à la langue, publiez dans leur fil respectif.
Réponses:
Attention aux numéros spéciaux
Certaines langues ont des fonctions intégrées pour les places, exponentiation avec la base 2, n premier -ème, factoriel, ou d' autres procédures qui peuvent générer un grand nombre. Vérifiez si votre numéro appartient à l'une de ces catégories.
Et si ce n'est pas le cas, il peut arriver qu'un plus grand nombre qui convient à vos besoins et puisse être utilisé à la place.
la source
1.01e6
itérations sont suffisantes,1e7
économise 3 octets au détriment du temps d'exécution.Utiliser des opérateurs booléens au niveau du bit
Certaines langues ont des bits ET, OU, XOR et parfois NON.
Exprimer un grand nombre spécifique sous la forme d'une combinaison au niveau du bit du résultat d'une exponentiation ou d'un décalage à gauche et d'un autre nombre peut vous aider à atteindre précisément le nombre dont vous avez besoin. Cela ne vaut généralement la peine que si les chiffres deviennent assez élevés.
Par exemple,
2147483722
est de 10 octets, mais2<<30^74
(2 ^ 31 XOR au niveau du bit avec 74) n'est que de 8.la source
bc
). Et XOR n'est jamais plus utile que+
et-
: dans ce cas, xor et add donnent le même résultat, mais dans tous les cas il y a un entier qui peut être ajouté ou soustrait pour produire le même résultat que xor avec un entier, et l'addend est pas plus grand et parfois plus court.1e9^2e9
.9<<49^7<<19
utilisant l'addition au lieu de xor?1286561280
en JavaScript et Perl (et probablement dans d'autres langages), et c'est une expression plus courte pour produire cette valeur que l'équivalent en utilisant+
ou-
.Utilisez des chaînes pour les nombres répétitifs
Pour les nombres de nature très répétitive, vous pouvez utiliser des chaînes et les convertir en nombre entier. Par exemple, en JavaScript
la source
1e100/9
dans ce cas.Utiliser la notation scientifique
La notation scientifique peut économiser des octets en cas de nombres longs. Par exemple:
la source
3564e-8
dans ce cas?.00003564
, qui est également un octet plus court à nouveau.Recherchez un autre numéro à utiliser à la place
Cela peut sembler une non-réponse, mais il n'est pas toujours évident qu'un plus grand nombre peut être calculé par un code plus court. Un exemple dont je me souviens est Output a googol copies of a string , où les réponses évidentes nécessitent le calcul de 10 100 . Il s'avère que le calcul d'un multiple de 10 100 conduit à une réponse tout aussi correcte, mais dans certaines langues, plus courte. La réponse de Dennis utilise 100 100 , la mienne utilise 250 255 .
la source
es
si vous avez juste besoin d'un grand nombre mais ne vous souciez pas de sa valeur (ou que c'est toujours la même chose).Compression de base
Le code de décompression de base peut être assez complexe, mais si vous avez un nombre vraiment énorme, cela peut parfois aider à le compresser dans une base supérieure à 10.
Il est également utile que dans certaines langues, le code de compression de base soit très simple. Par exemple, PHP a
base64_decode(_)
, Python aint(_,36)
, JavaScript aparseInt(_,36)
, et de nombreux langages de golf ont des commandes de décompression de base. Par exemple, dans CJam:Cela contient un non imprimable. Essayez-le en ligne!
Cela donne:
la source
Utilisez des fractions exponentielles pour les grands nombres répétitifs
Supposons que vous vouliez générer le nombre composé de 100 1. Vous pouvez utiliser
int("1"*100)
,+"1".repeat(100)
etc., mais vous pouvez également profiter du fait qu'il est très proche deCela fonctionne mieux pour les nombres très répétitifs, tels que ceux composés d'un seul chiffre. Quelques chiffres répétés fonctionnent également assez bien:
Parfois, vous trouverez un autre motif étrange qui peut également être représenté assez sommairement dans cette méthode. Si vous aviez besoin
int("123456790"*11)
, par exemple:Attention cependant: les nombres comme ceux-ci
int("1234567890"*10)
n'ont pas une représentation aussi simple.la source
Utilisez Bitwise Left Shift pour l'exponentiation de 2
Bien qu'il existe de nombreuses langues qui prennent en charge l'opérateur pour l'exponentiation, certaines ne le font pas. Et celles qui ne le nécessitent pas nécessitent généralement des fonctions d'appel (ou des méthodes Class / Object), qui peuvent coûter quelques octets.
Mais vous pouvez enregistrer quelques octets lorsque vous devez augmenter 2 à la puissance n en utilisant l'opérateur de décalage à gauche Bit
<<
as1<<n
. Notez que cela ne vous fera économiser des octets que si n est supérieur ou égal à 17. Cependant, cela vous fera toujours économiser des octets si n est dynamique. Quelques exemples:la source
8<<9 // 4096
afin que nous puissions obtenir jusqu'à99<<61
6 octets, ce qui équivaut à6,917,529,027,641,081,856
économiser 13 octets!Théorème du reste chinois
Si de grands nombres entiers arbitraires apparaissent fréquemment, ou si la représentation de grands nombres entiers dans le langage de programmation cible coûte trop d'octets, vous pouvez envisager d'utiliser le théorème du reste chinois.
Choisissez quelques entiers relativement premiers m i > = 2, et vous pouvez exprimer un grand nombre de 0 à lcm (m 1 , m 2 , ..., m i ) -1
Par exemple, je choisis 2, 3, 5, 11, 79, 83, 89, 97, puis je peux exprimer le nombre inférieur à 18680171730 uniquement. 10000000000 (1e10) peut être exprimé comme 0,1,0,1,38,59,50,49 (1e10 mod 2, 3 ..., 97) qui ne doivent pas être exprimés en tant que classe / structure spéciale Big Integer qui pourrait sauver quelques octets dans un langage de programmation.
L'addition et la soustraction peuvent être effectuées directement à l'aide de cette représentation. Exemple:
la source
Utilisez un remplissage de chaîne (si possible)
Si un grand nombre comprend un chiffre répétitif au début ou à la fin, vous pourrez peut-être enregistrer des octets en utilisant l'une des méthodes de remplissage de votre langue pour construire une chaîne du nombre que vous recherchez, que vous pouvez ensuite convertir en entier.
Exemple
Pour générer le nombre
1111111111111111111111112
(25 octets) en JavaScript (ES8):la source
Utiliser des exposants
Si votre langue a un opérateur exposant, vous pourriez être en mesure de l'utiliser pour générer, sinon le nombre que vous voulez, au moins un nombre, vous pouvez effectuer un calcul simple ou 2 pour arriver à votre numéro. Même sans opérateur, vous pouvez toujours enregistrer des octets avec une fonction ou une méthode intégrée.
Exemple
Le nombre entier en toute sécurité maximum JavaScript est
9007199254740991
, qui est de 16 chiffres. Dans ES7, cela peut être calculé avec les 7 octets suivants:L'équivalent dans ES6 et les versions antérieures, bien qu'il ait la même longueur que l'entier lui-même dans cette instance, montre que l'utilisation d'une méthode plus détaillée ne vous coûtera pas nécessairement des octets.
Ce qui précède, cependant, peut fonctionner plus court si, par exemple, vous avez déjà un
Math
alias pour un seul caractère ailleurs dans votre code.la source
Utilisez des fractions à la place du flotteur
Exemple:
1./3
à la place de0.333333333
la source