Eu estive considerando uma avaliação rápida das mãos de poker em Python. Ocorreu-me que uma maneira de acelerar o processo seria representar todos os rostos e naipes de cartas como números primos e multiplicá-los para representar as mãos. Para 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]
E
def HashVal(self):
return PokerCard.facePrimes[self.cardFace] * PokerCard.suitPrimes[self.cardSuit]
Isso daria a cada mão um valor numérico que, através do módulo, poderia me dizer quantos reis existem na mão ou quantos corações. Por exemplo, qualquer mão com cinco ou mais tacos dividiria uniformemente por 2 ^ 5; qualquer mão com quatro reis se dividiria uniformemente por 59 ^ 4, etc.
O problema é que uma mão de sete cartas como AcAdAhAsKdKhKs tem um valor de hash de aproximadamente 62,7 quadrilhões, o que levaria consideravelmente mais de 32 bits para representar internamente. Existe uma maneira de armazenar números tão grandes em Python que me permita executar operações aritméticas nele?
fonte
Respostas:
O Python suporta um tipo inteiro "bignum" que pode funcionar com números arbitrariamente grandes. No Python 2.5+, esse tipo é chamado
long
e é separado doint
tipo, mas o intérprete usará automaticamente o que for mais apropriado. No Python 3.0+, oint
tipo foi descartado completamente.Porém, isso é apenas um detalhe de implementação - desde que você tenha a versão 2.5 ou melhor, apenas execute operações matemáticas padrão e qualquer número que exceda os limites da matemática de 32 bits será automaticamente (e transparentemente) convertido em um bignum.
Você pode encontrar todos os detalhes sangrentos no PEP 0237 .
fonte
long
os comprimentos de s (em dígitos) serão armazenados como números inteiros de 32 bits sem sinal, até 4.294.967.295 dígitos, o que significa que eles podem facilmente segurar hold ** (4 * 10 ** 6 ), que é "apenas" 832.951 dígitos. No entanto, φ não é um número inteiro; portanto, você precisará usar um decimal (bignum de ponto flutuante do Python) para calcular o número. Você pode armazenar o resultadolong
posteriormente, no entanto.long
é o único tipo inteiro no 3.0, mas é chamadoint
. (E o velhoint
se foi.)python suporta inteiros arbitrariamente grandes naturalmente:
exemplo:
Você pode até obter, por exemplo, um valor inteiro enorme, fib (4000000).
Mas ainda assim ele faz não (por enquanto) suporta uma arbitrariamente grande bóia !!
Se você precisar de um flutuador grande, grande, verifique o módulo decimal. Existem exemplos de uso nesses fóruns: OverflowError: (34, 'Resultado muito grande')
Outra referência: http://docs.python.org/2/library/decimal.html
Você pode até usar o módulo gmpy se precisar de uma aceleração (o que provavelmente é do seu interesse): Manipular grandes números no código
Outra referência: https://code.google.com/p/gmpy/
fonte
Você pode fazer isso por diversão, mas fora isso não é uma boa ideia. Não aceleraria nada que eu pudesse pensar.
Colocar as cartas em uma mão será uma operação de fatoração inteira que é muito mais cara do que apenas acessar uma matriz.
Adicionar cartões seria multiplicação e remover divisão de cartões, ambos grandes números com várias palavras, que são operações mais caras do que adicionar ou remover elementos das listas.
O valor numérico real de uma mão não diz nada. Você precisará fatorar os números primos e seguir as regras do Poker para comparar as duas mãos. h1 <h2 para essas mãos não significa nada.
fonte
python suporta inteiros arbitrariamente grandes naturalmente:
fonte
O intérprete python cuidará disso para você, você só precisa fazer suas operações (+, -, *, /) e funcionará normalmente.
O
int
valor é ilimitado.Cuidado ao fazer a divisão, por padrão, o quociente é transformado
float
, masfloat
não suporta números tão grandes. Se você receber uma mensagem de erro dizendofloat
que não suporta números tão grandes, significa que o quociente é muito grande para ser armazenado.float
Você precisará usar a divisão do piso (//
).Ele ignora qualquer decimal que vem depois do ponto decimal, assim o resultado será
int
, para que você possa obter um resultado numérico grande.10//3
Saídas3
10//4
saídas2
fonte