A deck of cards is 52. A hand is 5 cards from the 52 (cannot have a duplicate).
What is the least amount of bits to represent a 5 card hand and how?
A hand is NOT order dependent (KQ = QK). 64329 = 96432
Yes, can use 52 bits. That can represent a hand of any number of cards.
Given a hand is exactly 5 cards is there a way to represent it with less than 52 bits.
A single card can be represented with 6 bits = 64. So could just use 6 bits * 5 cards = 30 bits. But that would be order dependent. I could just sort and this should work. If that would not work please let me know.
Is there a way to get the key to 32 bits or under and not have to sort the 5 card tuple.
This is for poker simulations and sorting would be a lot of overhead compared to just generating the hand. If I have a dictionary with the relative value of each hand it is two simple lookups and a comparison to compare the value of two hands. If I have to sort the hands first that is large compared to two lookups and a comparison. In a simulation will compare millions. I will not get sorted hands from the simulation. The sort is not simple like 52 51 50 49 48 before 52 51 50 49 47. You can have straight flush quads ....
There are 2598960 possible 5 card hands. That is the number of rows. The key is the 5 cards. I would like to get a key that is 32 bits or under where the the cards do not need to be sorted first.
Cannot just order the list as many hands tie. Suit are spade, club, diamond, and heart. 7c 8c 2d 3d 4s = 7s 8s 2c 3c 4h. There is a large number of ties.
The next step is 64 bits and will take the hit of the sort rather than double the size of the key.
I tested and SortedSet<int> quickSort = new SortedSet<int>() { i, j, k, m, n };
doubles the time of the operation but I still may do it.
It gets more complex. I need to be able to represent a boat as twos over fives (22255). So sorting them breaks that. I know you are going to say but that is fast. Yes it is fast and trivial but I need as fast as possible.
C# for the accepted answer:
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("");
}