Saya telah mempertimbangkan evaluasi tangan poker cepat dengan Python. Terpikir oleh saya bahwa salah satu cara untuk mempercepat prosesnya adalah dengan merepresentasikan semua wajah dan corak kartu sebagai bilangan prima dan mengalikannya untuk merepresentasikan tangan. Sedikit pun:
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]
DAN
def HashVal(self):
return PokerCard.facePrimes[self.cardFace] * PokerCard.suitPrimes[self.cardSuit]
Ini akan memberi setiap tangan nilai numerik yang, melalui modulo bisa memberi tahu saya berapa banyak raja di tangan atau berapa banyak hati. Misalnya, setiap tangan dengan lima atau lebih klub di dalamnya akan dibagi rata dengan 2 ^ 5; tangan mana pun dengan empat raja akan membagi rata dengan 59 ^ 4, dll.
Masalahnya adalah bahwa tujuh kartu seperti AcAdAhAsKdKhKs memiliki nilai hash sekitar 62,7 kuadriliun, yang akan membutuhkan lebih dari 32 bit untuk diwakili secara internal. Apakah ada cara untuk menyimpan bilangan besar dengan Python yang memungkinkan saya melakukan operasi aritmatika?
sumber
Jawaban:
Python mendukung tipe integer "bignum" yang dapat bekerja dengan bilangan besar secara sembarangan. Dalam Python 2.5+, tipe ini dipanggil
long
dan terpisah dariint
tipenya, tetapi interpreter akan secara otomatis menggunakan mana yang lebih sesuai. Di Python 3.0+,int
jenisnya telah dihapus sepenuhnya.Itu hanya detail implementasi, meskipun - selama Anda memiliki versi 2.5 atau lebih baik, cukup lakukan operasi matematika standar dan angka apa pun yang melebihi batas matematika 32-bit akan secara otomatis (dan transparan) diubah menjadi bignum.
Anda dapat menemukan semua detail berdarah di PEP 0237 .
sumber
long
panjang s (dalam digit) disimpan sebagai bilangan bulat 32-bit unsigned, hingga 4.294.967.295 digit, yang berarti dapat dengan mudah menampung φ ** (4 * 10 ** 6 ), yang "hanya" 832.951 digit. Namun, φ bukanlah bilangan bulat, jadi Anda perlu menggunakan Desimal (bignum floating-point Python) untuk menghitung angka tersebut. Anda dapat menyimpan hasilnyalong
nanti.long
adalah satu-satunya tipe bilangan bulat di 3.0, tetapi dinamaiint
. (Dan yang lamaint
hilang.)python mendukung sewenang-wenang besar bilangan bulat secara alami:
contoh:
>>> 10**1000 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Anda bahkan bisa mendapatkan, misalnya nilai integer yang sangat besar, fib (4000000).
Tapi tetap saja tidak (untuk saat ini) mendukung float besar yang sewenang-wenang !!
Jika Anda membutuhkan satu besar, besar, pelampung kemudian periksa Modul desimal. Ada contoh penggunaan pada forun ini: OverflowError: (34, 'Result too large')
Referensi lain: http://docs.python.org/2/library/decimal.html
Anda bahkan dapat menggunakan modul gmpy jika Anda membutuhkan percepatan (yang mungkin menarik bagi Anda): Menangani angka besar dalam kode
Referensi lain: https://code.google.com/p/gmpy/
sumber
Anda bisa melakukan ini untuk kesenangan, tapi selain itu itu bukan ide yang bagus. Itu tidak akan mempercepat apapun yang dapat saya pikirkan.
Mendapatkan kartu di tangan akan menjadi operasi pemfaktoran bilangan bulat yang jauh lebih mahal daripada hanya mengakses array.
Menambahkan kartu akan menjadi perkalian, dan menghapus pembagian kartu, keduanya dari bilangan multi-kata besar, yang merupakan operasi yang lebih mahal daripada menambah atau menghapus elemen dari daftar.
Nilai numerik sebenarnya dari sebuah tangan tidak akan memberi tahu Anda apa pun. Anda perlu memfaktorkan bilangan prima dan mengikuti aturan Poker untuk membandingkan dua tangan. h1 <h2 untuk tangan seperti itu tidak ada artinya.
sumber
python mendukung bilangan bulat besar secara alami:
In [1]: 59**3*61**4*2*3*5*7*3*5*7 Out[1]: 62702371781194950 In [2]: _ % 61**4 Out[2]: 0
sumber
Penerjemah python akan menanganinya untuk Anda, Anda hanya perlu melakukan operasi Anda (+, -, *, /), dan itu akan berfungsi seperti biasa.
The
int
nilai tidak terbatas.Hati-hati saat melakukan pembagian, secara default hasil bagi berubah menjadi
float
, tetapifloat
tidak mendukung angka yang begitu besar. Jika Anda mendapatkan pesan kesalahan yang mengatakanfloat
tidak mendukung angka yang begitu besar, maka itu berarti hasil bagi terlalu besar untuk disimpan difloat
Anda harus menggunakan pembagian lantai (//
).Ini mengabaikan desimal apa pun yang muncul setelah koma desimal, dengan cara ini, hasilnya adalah
int
, sehingga Anda bisa mendapatkan hasil angka yang besar.>>>10//3 3 >>>10//4 2
sumber