He estado considerando la evaluación rápida de manos de póker en Python. Se me ocurrió que una forma de acelerar el proceso sería representar todas las caras y palos de las cartas como números primos y multiplicarlos para representar las manos. A whit:
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]
Y
def HashVal(self):
return PokerCard.facePrimes[self.cardFace] * PokerCard.suitPrimes[self.cardSuit]
Esto le daría a cada mano un valor numérico que, a través del módulo, podría decirme cuántos reyes hay en la mano o cuántos corazones. Por ejemplo, cualquier mano con cinco o más clubes se dividiría en partes iguales por 2 ^ 5; cualquier mano con cuatro reyes se dividiría en partes iguales por 59 ^ 4, etc.
El problema es que una mano de siete cartas como AcAdAhAsKdKhKs tiene un valor hash de aproximadamente 62.7 billones, lo que tomaría considerablemente más de 32 bits para representar internamente. ¿Hay alguna manera de almacenar números tan grandes en Python que me permitan realizar operaciones aritméticas en él?
fuente
Respuestas:
Python admite un tipo entero "bignum" que puede funcionar con números arbitrariamente grandes. En Python 2.5+, este tipo se llama
long
y es independiente delint
tipo, pero el intérprete usará automáticamente el que sea más apropiado. En Python 3.0+, elint
tipo se ha eliminado por completo.Sin embargo, eso es solo un detalle de implementación: siempre que tenga la versión 2.5 o superior, solo realice operaciones matemáticas estándar y cualquier número que exceda los límites de las matemáticas de 32 bits se convertirá automáticamente (y de manera transparente) en un bignum.
Puede encontrar todos los detalles sangrientos en PEP 0237 .
fuente
long
las longitudes de s (en dígitos) se almacenan como enteros de 32 bits sin signo, hasta 4,294,967,295 dígitos, lo que significa que pueden contener fácilmente φ ** (4 * 10 ** 6 ), que es "solo" 832,951 dígitos. Sin embargo, φ no es un número entero, por lo que necesitará usar un Decimal (punto de coma flotante de Python) para calcular el número.long
Sin embargo, puede almacenar el resultado posteriormente.long
es el único tipo entero en 3.0, pero se llama asíint
. (Y lo viejoint
se fue.)Python admite enteros arbitrariamente grandes naturalmente:
ejemplo:
Incluso podría obtener, por ejemplo, un valor entero enorme, fib (4000000).
¡Pero todavía no es compatible (por ahora) con un flotador arbitrariamente grande !
Si necesita un flotador grande, grande, compruebe el módulo decimal. Hay ejemplos de uso en estos foros: OverflowError: (34, 'Resultado demasiado grande')
Otra referencia: http://docs.python.org/2/library/decimal.html
Incluso puede usar el módulo gmpy si necesita una aceleración (que probablemente sea de su interés): manejo de números grandes en el código
Otra referencia: https://code.google.com/p/gmpy/
fuente
Podrías hacer esto por diversión, pero aparte de eso, no es una buena idea. No aceleraría nada en lo que pueda pensar.
Obtener las tarjetas en una mano será una operación de factorización de enteros que es mucho más costosa que simplemente acceder a una matriz.
Agregar tarjetas sería una multiplicación y eliminar la división de tarjetas, tanto de números grandes de varias palabras, que son operaciones más caras que agregar o eliminar elementos de las listas.
El valor numérico real de una mano no le dirá nada. Necesitarás factorizar los números primos y seguir las reglas de Poker para comparar dos manos. h1 <h2 para tales manos no significa nada.
fuente
Python admite enteros arbitrariamente grandes naturalmente:
fuente
El intérprete de Python lo manejará por usted, solo tiene que hacer sus operaciones (+, -, *, /), y funcionará normalmente.
El
int
valor es ilimitado.Tenga cuidado al hacer la división, por defecto, el cociente se convierte
float
, perofloat
no admite números tan grandes. Si recibe un mensaje de error que dicefloat
que no admite números tan grandes, significa que el cociente es demasiado grande para ser almacenadofloat
, tendrá que usar la división de piso (//
).Ignora cualquier decimal que viene después del punto decimal, de esta manera, el resultado será
int
, por lo que puede tener un resultado de gran número.10//3
Salidas3
10//4
salidas2
fuente