1

This is for a poker lookup
In this case a hand is 7 cards (it is really the best 5 but can ignore that)
In a deck of 52 have 133,784,560 7 card hands - the order of the cards does not matter

Cards can be identified as 0-51 or 1-52

For each hand I can assign a score (some will be ties)

What I need is an unique identifier for the 133,784,560 hands that is not order dependent

When I ignore suite and just use rank 1-13
I just associate a prime with each and multiply the primes

1   2   3   4    5   6   7   8   9  10  11  12  13
2   3   5   7   11  13  17  19  23  29  31  37  41  

Primes for the first 52 is a much bigger number - the product is bigger than int64

I could use card1 + card2*53^1 + card3*53^2 ...
The problem there is must sort the cards. I am evaluating billions of hands and a sort is very costly.

Assume it was only 2 cards - need that for 7
Key = f(a,b) = f(b,a)

From the accepted answer this is the solution in C# - unfortunately run out of memory

    public void UniqueIdentifires52x7()
    {
        UInt64 iPow;
        UInt64 jPow;
        UInt64 kPow;
        UInt64 mPow;
        UInt64 nPow;
        UInt64 pPow;
        UInt64 qPow;
        UInt64 id;
        int counter = 0;
        HashSet<UInt64> hs = new HashSet<UInt64>();
        for (int i = 51; i >= 6; i--)
        {
            iPow = (UInt64)Math.Pow(2, i);
            for (int j = i - 1; j >= 5; j--)
            {
                jPow = (UInt64)Math.Pow(2, j);
                for (int k = j - 1; k >= 4; k--)
                {
                    kPow = (UInt64)Math.Pow(2, k);
                    for (int m = k - 1; m >= 3; m--)
                    {
                        mPow = (UInt64)Math.Pow(2, m);
                        for (int n = m - 1; n >= 2; n--)
                        {
                            nPow = (UInt64)Math.Pow(2, n);
                            for (int p = n - 1; p >= 1; p--)
                            {
                                pPow = (UInt64)Math.Pow(2, p);
                                for (int q = p - 1; q >= 0; q--)
                                {
                                    qPow = (UInt64)Math.Pow(2, q);
                                    id = iPow + jPow + kPow + mPow + nPow + pPow + qPow;
                                    //Debug.WriteLine(id);
                                    hs.Add(id);
                                    counter++;
                                    if(counter % 1000000 == 0)
                                        Debug.WriteLine(counter.ToString("N0") + " " + hs.Count().ToString("N0"));
                                }
                            }
                        }
                    }
                }
            }
        }
        Debug.WriteLine(counter.ToString("N0") + " " + hs.Count().ToString("N0"));
    } 
paparazzo
  • 330

2 Answers2

3

An easy unique identifier for 7-element subsets of a set containing numbers $0, 1, \ldots, 51$ is $$ \{c_1, c_2, c_3, c_4, c_5, c_6, c_7\} \mapsto \sum_{i=1}^7 2^{c_i} $$ For example, if you label the cards from 2 of clubs through A of spades, then the hand consisting of 4 deuces and the AKQ of spades would be $$ 2^0+2^{14}+2^{27}+2^{40}+2^{49} + 2^{50}+2^{51} $$ This is not a dense packing, but id does fit into 64-bit integers, and can also be represented exactly as double (64-bit floats, which have 53 bits of mantissa).

No sorting is needed.

Mark Fischler
  • 41,743
1

If you use the first $52$ primes, the biggest product for a $7$-card hand is

$$199\cdot211\cdot223\cdot227\cdot229\cdot233\cdot239\approx2^{54.6}$$

Barry Cipra
  • 79,832