J'ai envisagé une évaluation rapide des mains de poker en Python. Il m'est apparu qu'une façon d'accélérer le processus serait de représenter toutes les faces et combinaisons de cartes sous forme de nombres premiers et de les multiplier ensemble pour représenter les mains. Pour Pentecôte:
class PokerCard:
faces = '23456789TJQKA'
suits = 'cdhs'
facePrimes = [11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 53, 59, 61]
suitPrimes = [2, 3, 5, 7]
ET
def HashVal(self):
return PokerCard.facePrimes[self.cardFace] * PokerCard.suitPrimes[self.cardSuit]
Cela donnerait à chaque main une valeur numérique qui, via modulo, pourrait me dire combien de rois sont dans la main ou combien de cœurs. Par exemple, n'importe quelle main avec cinq clubs ou plus se diviserait également par 2 ^ 5; n'importe quelle main avec quatre rois se diviserait également par 59 ^ 4, etc.
Le problème est qu'une main à sept cartes comme AcAdAhAsKdKhKs a une valeur de hachage d'environ 62,7 quadrillions, ce qui prendrait considérablement plus de 32 bits à représenter en interne. Existe-t-il un moyen de stocker de si grands nombres en Python qui me permettra d'effectuer des opérations arithmétiques dessus?
la source
Réponses:
Python prend en charge un type entier "bignum" qui peut fonctionner avec des nombres arbitrairement grands. Dans Python 2.5+, ce type est appelé
long
et est distinct duint
type, mais l'interpréteur utilisera automatiquement celui qui est le plus approprié. Dans Python 3.0+, leint
type a été complètement supprimé.Ce n'est qu'un détail d'implémentation, cependant - tant que vous avez la version 2.5 ou supérieure, effectuez simplement des opérations mathématiques standard et tout nombre qui dépasse les limites des mathématiques 32 bits sera automatiquement (et de manière transparente) converti en bignum.
Vous pouvez trouver tous les détails sanglants dans la PEP 0237 .
la source
long
les longueurs de s (en chiffres) sont stockées sous forme d'entiers 32 bits non signés, jusqu'à 4294967295 chiffres, ce qui signifie qu'ils peuvent facilement contenir φ ** (4 * 10 ** 6 ), qui ne contient «que» 832 951 chiffres. Cependant, φ n'est pas un entier, vous devrez donc utiliser un décimal (bignum à virgule flottante de Python) pour calculer le nombre.long
Cependant, vous pouvez stocker le résultat dans une suite.long
est le seul type entier dans 3.0, mais il est nomméint
. (Et l'ancienint
est parti.)python prend naturellement en charge les entiers arbitrairement grands :
exemple:
Vous pouvez même obtenir, par exemple, une valeur entière énorme, fib (4000000).
Mais il ne supporte toujours pas (pour l'instant) un flotteur arbitrairement grand !!
Si vous avez besoin d'un grand, grand flotteur, vérifiez le module décimal. Il existe des exemples d'utilisation sur ces foruns: OverflowError: (34, 'Result too large')
Autre référence: http://docs.python.org/2/library/decimal.html
Vous pouvez même utiliser le module gmpy si vous avez besoin d'une accélération (ce qui est susceptible de vous intéresser): Gestion de gros nombres dans le code
Une autre référence: https://code.google.com/p/gmpy/
la source
Vous pouvez le faire pour le plaisir, mais à part ça, ce n'est pas une bonne idée. Cela n'accélérerait rien à quoi je puisse penser.
Obtenir les cartes dans une main sera une opération de factorisation entière qui est beaucoup plus coûteuse que d'accéder simplement à un tableau.
L'ajout de cartes serait une multiplication et la suppression de la division des cartes, tous deux de grands nombres à plusieurs mots, qui sont des opérations plus coûteuses que l'ajout ou la suppression d'éléments de listes.
La valeur numérique réelle d'une main ne vous dira rien. Vous devrez factoriser les primes et suivre les règles du poker pour comparer deux mains. h1 <h2 pour de telles mains ne signifie rien.
la source
python prend naturellement en charge les entiers arbitrairement grands:
la source
L'interpréteur python le gérera pour vous, il vous suffit de faire vos opérations (+, -, *, /), et cela fonctionnera normalement.
La
int
valeur est illimitée.Attention lors de la division, par défaut, le quotient est converti en
float
, maisfloat
ne prend pas en charge ces grands nombres. Si vous obtenez un message d'erreur indiquant quefloat
ne prend pas en charge ces grands nombres, cela signifie que le quotient est trop grand pour être stocké dansfloat
vous devrez utiliser floor division (//
).Il ignore toute décimale qui vient après la virgule décimale, de cette façon, le résultat sera
int
, donc vous pouvez avoir un résultat en grand nombre.10//3
Les sorties3
10//4
les sorties2
la source