Setumpuk kartu adalah 52. Tangan adalah 5 kartu dari 52 (tidak dapat memiliki duplikat).
Berapa jumlah bit paling sedikit untuk mewakili kartu 5 tangan dan bagaimana?
Tangan TIDAK tergantung pesanan (KQ = QK). 64329 = 96432
Ya, bisa menggunakan 52 bit. Itu bisa mewakili tangan sejumlah kartu.
Diberi tangan adalah tepat 5 kartu apakah ada cara untuk mewakilinya dengan kurang dari 52 bit.
Satu kartu dapat direpresentasikan dengan 6 bit = 64. Jadi bisa saja menggunakan 6 bit * 5 kartu = 30 bit. Tapi itu tergantung pesanan. Saya bisa menyortir dan ini seharusnya berhasil. Jika itu tidak berhasil tolong beri tahu saya.
Apakah ada cara untuk mendapatkan kunci 32 bit atau di bawah dan tidak perlu mengurutkan tuple 5 kartu.
Ini untuk simulasi poker dan pengurutan akan banyak overhead dibandingkan dengan hanya menghasilkan tangan. Jika saya memiliki kamus dengan nilai relatif masing-masing tangan itu adalah dua pencarian sederhana dan perbandingan untuk membandingkan nilai dua tangan. Jika saya harus mengurutkan tangan pertama yang besar dibandingkan dengan dua pencarian dan perbandingan. Dalam simulasi akan membandingkan jutaan. Saya tidak akan mendapatkan tangan yang disortir dari simulasi. Jenisnya tidak sederhana seperti 52 51 50 49 48 sebelum 52 51 50 49 47. Anda dapat memiliki paha depan flush lurus ....
Ada 2598960 kemungkinan 5 kartu. Itu adalah jumlah baris. Kuncinya adalah 5 kartu. Saya ingin mendapatkan kunci yang 32 bit atau di bawah di mana kartu tidak perlu disortir terlebih dahulu.
Tidak bisa hanya memesan daftar sebanyak dasi tangan. Setelannya adalah sekop, pentungan, berlian, dan hati. 7c 8c 2d 3d 4s = 7s 8s 2c 3c 4h. Ada banyak ikatan.
Langkah selanjutnya adalah 64 bit dan akan menerima pukulan semacam itu daripada menggandakan ukuran kunci.
Saya menguji dan SortedSet<int> quickSort = new SortedSet<int>() { i, j, k, m, n };
menggandakan waktu operasi tetapi saya masih bisa melakukannya.
Itu menjadi lebih kompleks. Saya harus bisa mewakili perahu sebagai berpasangan lima (22255). Jadi memilah mereka istirahat itu. Saya tahu Anda akan mengatakan tetapi itu cepat. Ya itu cepat dan sepele tetapi saya perlu secepat mungkin.
C # untuk jawaban yang diterima:
private int[] DeckXOR = new int[] {0x00000001,0x00000002,0x00000004,0x00000008,0x00000010,0x00000020,0x00000040,
0x00000080,0x00000100,0x00000200,0x00000400,0x00000800,0x00001000,0x00002000,
0x00004000,0x00008000,0x00010000,0x00020000,0x00040000,0x00080000,0x00100000,
0x00200000,0x00400000,0x00800000,0x01000000,0x02000000,0x04000000,0x07fe0000,
0x07c1f000,0x0639cc00,0x01b5aa00,0x056b5600,0x04ed6900,0x039ad500,0x0717c280,
0x049b9240,0x00dd0cc0,0x06c823c0,0x07a3ef20,0x002a72e0,0x01191f10,0x02c55870,
0x007bbe88,0x05f1b668,0x07a23418,0x0569d998,0x032ade38,0x03cde534,0x060c076a,
0x04878b06,0x069b3c05,0x054089a3};
public void PokerProB()
{
Stopwatch sw = new Stopwatch();
sw.Start();
HashSet<int> cardsXOR = new HashSet<int>();
int cardXOR;
int counter = 0;
for (int i = 51; i >= 4; i--)
{
for (int j = i - 1; j >= 3; j--)
{
for (int k = j - 1; k >= 2; k--)
{
for (int m = k - 1; m >= 1; m--)
{
for (int n = m - 1; n >= 0; n--)
{
counter++;
cardXOR = DeckXOR[i] ^ DeckXOR[j] ^ DeckXOR[k] ^ DeckXOR[m] ^ DeckXOR[n];
if (!cardsXOR.Add(cardXOR))
Debug.WriteLine("problem");
}
}
}
}
}
sw.Stop();
Debug.WriteLine("Count {0} millisec {1} ", counter.ToString("N0"), sw.ElapsedMilliseconds.ToString("N0"));
Debug.WriteLine("");
}
sumber
Jawaban:
Bob Jenkins menjelaskan kode semacam itu di situsnya , dan dari situ kita dapat mengekstrak array
sumber
Bagaimana cara kerja representasi? Ada berbagai opsi, dengan pengorbanan yang berbeda. Saya daftar dua di bawah ini.
Kamus kode-keras
Dalam hal ini, jumlah kartu 5 kartu yang mungkin cukup kecil sehingga Anda hanya bisa memiliki kamus kode keras yang mencantumkan semua kartu 2598960, dan Anda mewakili tangan dengan indeksnya di kamus (diwakili dalam biner).
Dengan kata lain, kamus dapat berupa daftar tangan yang diurutkan. Masing-masing tangan adalah 5-tupel kartu di tangan, dalam urutan diurutkan. Anda dapat mencari di kamus menggunakan pencarian biner dan menemukan indeks yang sesuai; dan diberi indeks, Anda dapat menemukan tangan yang sesuai. Atau, Anda dapat menyimpan kamus sebagai peta hash yang memetakan dari tangan ke indeksnya. Indeks adalah bilangan bulat antara 0 dan 2598959, sehingga dapat direpresentasikan menggunakan 23 bit.
Pendekatan ini akan bekerja dan sangat sederhana untuk diprogram, tetapi boros dalam ruang (ukuran program yang dapat dieksekusi).
Pemeringkatan / unranking
Atau, jika Anda peduli, ada metode yang lebih baik. Lihat, misalnya, salah satu referensi berikut:
https://en.wikipedia.org/wiki/Combinatorial_number_system
Sisi Timur, Sisi Barat . Catatan kuliah, Herbert S. Wilf, 14 Agustus 1999. Bagian 3.7-3.8.
https://computationalcombinatorics.wordpress.com/2012/09/10/ranking-and-unranking-of-combinations-and-permutations/
/programming//q/3143142/781723
Topik umum dikenal sebagai "peringkat (dan unranking) kombinasi". Ini sedikit lebih kompleks untuk diimplementasikan dan dipahami, tetapi hindari kebutuhan untuk memasukkan kamus kode-keras dalam program.
sumber
Anda dapat mengurutkan lima item dan secara bersamaan memeriksa duplikat tanpa perbandingan pada beberapa prosesor: Asumsikan prosesor memiliki instruksi cepat yang menentukan posisi set bit tertinggi, dan instruksi cepat menghitung angka dengan hanya set bit ke-n .
Biarkan bit (n) menjadi angka dengan set bit ke-n. Biarkan tertinggi_bit (x) menjadi jumlah bit tertinggi yang diatur dalam angka x, dengan nilai yang tidak ditentukan jika x = 0. Misalkan x ^ y menjadi eksklusif-atau dari x dan y.
Diberikan lima angka a, b, c, d dan e, masing-masing dari 0 hingga 51, mewakili lima kartu di tangan.
Biarkan x = bit (a) ^ bit (b) ^ bit (c) ^ bit (d) ^ bit (e).
Biarkan A = tertinggi_bit (x), ubah x menjadi x ^ bit (A).
Biarkan B = tertinggi_bit (x), ubah x menjadi x ^ bit (B).
Biarkan C = tertinggi_bit (x), ubah x menjadi x ^ bit (C).
Biarkan D = tertinggi_bit (x), ubah x menjadi x ^ bit (D).
Biarkan E = tertinggi_bit (x).
Jika x = 0 maka ada duplikat di nomor a, b, c, d, dan e. Kalau tidak, gunakan bit A * (24) + B * bit (18) + C * bit (12) + D * bit (6) + E sebagai pengodean tangan, di mana A, B, C, D, dan E didefinisikan seperti di atas. Ini mengkodekan tangan sebagai string 30-bit, sambil melakukan penyortiran dengan cara yang sangat efisien.
sumber