एक 5 कार्ड पोकर हाथ का प्रतिनिधित्व करें


11

कार्ड का एक डेक 52 है। 52 में से एक हाथ 5 कार्ड है (एक डुप्लिकेट नहीं हो सकता है)।

5 कार्ड हाथ का प्रतिनिधित्व करने के लिए बिट्स की सबसे कम राशि क्या है और कैसे?
एक हाथ आदेश पर निर्भर नहीं है (KQ = QK)। 64329 = 96432

हाँ, 52 बिट्स का उपयोग कर सकते हैं। यह किसी भी संख्या में कार्ड का एक हाथ का प्रतिनिधित्व कर सकता है।

एक हाथ दिया 5 कार्ड बिल्कुल 52 बिट्स से कम का प्रतिनिधित्व करने का एक तरीका है।

एक एकल कार्ड को 6 बिट्स = 64 के साथ दर्शाया जा सकता है। इसलिए केवल 6 बिट्स * 5 कार्ड्स = 30 बिट्स का उपयोग किया जा सकता है। लेकिन यह आदेश पर निर्भर होगा। मैं बस छांट सकता था और यह काम करना चाहिए। अगर वह काम नहीं करेगा तो कृपया मुझे बताएं।

क्या 32 बिट्स या उससे कम की कुंजी प्राप्त करने का कोई तरीका है और 5 कार्ड ट्यूपल को क्रमबद्ध नहीं करना है।

यह पोकर सिमुलेशन के लिए है और छँटाई केवल हाथ पैदा करने की तुलना में बहुत अधिक ओवरहेड होगी। यदि मेरे पास प्रत्येक हाथ के सापेक्ष मूल्य के साथ एक शब्दकोश है तो यह दो सरल लुकअप है और दो हाथों के मूल्य की तुलना करना है। अगर मुझे पहले हाथ को छाँटना है जो दो लुक और तुलना की तुलना में बड़ा है। एक सिमुलेशन में लाखों की तुलना करेंगे। मैं अनुकार से हाथ नहीं मिलाऊंगा। ५२ ५० ५० ४ ९ ४ You से पहले ५२ ५१ ५० ४ ९ ४ before की तरह यह सरल नहीं है। आपके पास सीधे फ्लश क्वाड हो सकते हैं ...।

2598960 संभावित 5 कार्ड हाथ हैं। वह पंक्तियों की संख्या है। कुंजी 5 कार्ड है। मैं एक कुंजी प्राप्त करना चाहता हूं जो कि 32 बिट्स है या जहां कार्ड को पहले सॉर्ट करने की आवश्यकता नहीं है।

सूची को केवल कई हाथों से बाँधने का आदेश नहीं दे सकते। सूट कुदाल, क्लब, हीरा और दिल हैं। 7 सी 8 सी 2 डी 3 डी 4 एस = 7 एस 8 एस 2 सी 3 सी 4 एच। बड़ी संख्या में संबंध हैं।

अगला चरण 64 बिट्स है और कुंजी के आकार को दोगुना करने के बजाय सॉर्ट का हिट लेगा।

मैंने SortedSet<int> quickSort = new SortedSet<int>() { i, j, k, m, n };ऑपरेशन के समय का परीक्षण किया और युगल किया लेकिन मैं अभी भी कर सकता हूं।

यह अधिक जटिल हो जाता है। मुझे पत्नियों (22255) से अधिक के रूप में एक नाव का प्रतिनिधित्व करने में सक्षम होना चाहिए। इसलिए उन्हें छांटने से वह टूट जाता है। मुझे पता है कि आप कहने जा रहे हैं, लेकिन यह तेज है। हां यह तेज और तुच्छ है लेकिन मुझे जितनी जल्दी हो सके उतनी तेजी से जरूरत है।

स्वीकृत उत्तर के लिए C #:

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("");
}

4
एक हाथ से कोडित छँटाई एल्गोरिथ्म का उपयोग करें जो लंबाई की सूचियों को छाँटने के लिए काम करता है। 5. यह संभवतः आपके द्वारा उपयोग किए जा रहे लाइब्रेरी फंक्शन से अधिक तेज़ है।
युवल फिल्मस

1
मुझे समझ नहीं आ रहा है कि आप क्यों कहते हैं "सॉर्ट सरल नहीं है" । प्रकार है सरल - 1 से 52 के लिए एक नंबर करने के लिए प्रत्येक कार्ड कनवर्ट करते हैं, ताकि हाथ ताश के पत्तों की (लंबाई 5) एक सूची का प्रतिनिधित्व करती है। उस सूची को क्रमबद्ध करें। यह सिर्फ 5 पूर्णांकों की सूची को छांटने की समस्या है, जिसे बहुत तेजी से किया जा सकता है, जैसा कि युवल उल्लेख है। मेरा सुझाव है कि आप यह मानने से पहले माप लें कि यह बहुत धीमा है, लेकिन मेरा अनुमान है कि इस तरह की एक सूची को छांटना बहुत तेज होगा और यह रैंडम-एक्सेस मेमोरी रीड से भी तेज हो सकता है जो कैश में हिट नहीं होता है।
DW

@dw हाँ सॉर्ट सरल है लेकिन मैं जो कर रहा हूं (लाखों बार) वह सरल है। मैंने परीक्षण किया और एक समय दोगुना हो गया।
पापाराज़ो

1
@Paparazzi नहीं, युवल आपको अपनी खुद की छँटाई दिनचर्या लिखने के लिए कह रहा है जो विशेष रूप से 1 और 52 के बीच पाँच संख्याओं को छाँटने के लिए तैयार है। आपने एक पुस्तकालय दिनचर्या का उपयोग करने की कोशिश की, जो धीमी है क्योंकि यह इस से बहुत अधिक सामान्य है और क्योंकि पुनरावर्ती प्रकृति है। Quicksort की यह छोटी सूचियों पर बहुत ही अक्षम बनाता है।
डेविड रिचरबी

व्यवहार में, अधिकांश आइटम जो <= 16 बिट्स नहीं हैं, वे 32 बिट्स भी हो सकते हैं। इसलिए जब से आपको कम से कम 23 बिट्स की आवश्यकता होती है, कोई भी एन्कोडिंग जो <= 32 बिट्स का उपयोग करता है, वह संभवतः व्यवहार्य है। तुच्छ 6 बिट प्रति कार्ड * 5 कार्ड एन्कोडिंग काफी अच्छी तरह से काम करता है। वहाँ एक चेतावनी है: एक 32 बिट सरणी सूचकांक की तुलना में एक 23 बिट सरणी सूचकांक बहुत बेहतर है।
MSalters

जवाबों:


10

चलो एक हो कोड। का समता जाँच मैट्रिक्स बिट मैट्रिक्स है, ऐसे स्तंभों की न्यूनतम संख्या जिनकी XOR लुप्त होती है । निरूपित से कॉलम । हम प्रत्येक को बिट्स की बाइनरी संख्या के रूप में पहचान सकते हैं । वादा है कि किसी भी XOR है करने के लिए इन संख्याओं में से कभी नहीं है । इसके उपयोग से, आप अपने हाथ को को , जहांC[52,25,11]C27×521152A1,,A52Ai271100a,b,c,d,eAaAbAcAdAeXOR है। वास्तव में, यह स्पष्ट रूप से आदेश पर निर्भर नहीं करता है, और यदि दो हाथ टकराते हैं, तो XORing दो हैश मान देता है। संख्याएँ जिनका XOR शून्य है।H1,H2102|H1H2|10

बॉब जेनकिन्स अपनी साइट में इस तरह के एक कोड का वर्णन करता है , और उससे हम सरणी को निकाल सकते हैं

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

चूंकि पहले 27 वैक्टर हैंमिंग वजन 1 की सिर्फ 27 संख्याएं हैं, यह जांचने के लिए कि यह निर्माण सही है, यह सभी संभावित गैर-तुच्छ विचार करने के लिए पर्याप्त है। अंतिम 25 नंबरों के संयोजन, यह जाँच करते हुए कि उनके XORs का वजन हमेशा कम से कम 10 होता है। उदाहरण के लिए, पहले नंबर 0x07fe0000 में हैमिंग का वजन ठीक 10 है।252271=2251


मैं बिल्कुल पालन नहीं करता। एक हाथ के लिए कितने बिट्स की आवश्यकता होती है?
पापाराज़ो

इसके लिए 27 बिट्स चाहिए। आप किसी भी बड़ी संख्या में बिट्स का उपयोग कर सकते हैं।
युवल फिल्मस

धन्यवाद। मैंने परीक्षण किया और संख्या अद्वितीय और <= 32 बिट्स हैं। क्या मैं संख्या से 5 कार्ड प्राप्त कर सकता हूं? अगर ठीक न हो तो पूछना।
पापाराज़ो

हां, यह सरल रैखिक बीजगणित है। 5 लोगों के साथ लंबाई 52 के वेक्टर को वापस लाने के लिए आप सही मैट्रिक्स का उपयोग कर सकते हैं। मैं तुम्हें यह पता लगाने दूँगा।
युवल फिल्मस

13

यदि हमारे पास आकार का सेट है , तो आप बिट्स का उपयोग करके सेट के एक तत्व का प्रतिनिधित्व कर सकते हैं । आप कहते हैं कि 2598960 संभावित 5-कार्ड हाथ हैं। इसका मतलब है कि एक 5-कार्ड हाथ का प्रतिनिधित्व सिर्फ बिट्स का उपयोग करके किया जा सकता है । 22 बिट्स 30 बिट्स की तुलना में काफी कम है।एलजी n एलजी 2598960 = 22nlgnlg2598960=22

प्रतिनिधित्व कैसे काम करता है? विभिन्न ट्रेडऑफ़ के साथ विभिन्न विकल्प हैं। मैं नीचे दो सूचीबद्ध करता हूं।

हार्ड कोडित शब्दकोश

इस मामले में, संभावित 5-कार्ड हाथों की संख्या काफी छोटी है कि आप केवल एक हार्ड-कोडेड शब्दकोश हो सकते हैं जो सभी 2598960 हाथों को सूचीबद्ध करता है, और आप शब्दकोश में इसके सूचकांक द्वारा एक हाथ का प्रतिनिधित्व करते हैं (बाइनरी में प्रतिनिधित्व)।

दूसरे शब्दों में, शब्दकोश हाथों की क्रमबद्ध सूची हो सकती है। प्रत्येक हाथ छांटे हुए क्रम में कार्ड का 5-टपल है। आप द्विआधारी खोज का उपयोग करके शब्दकोश में एक हाथ देख सकते हैं और इसके संबंधित सूचकांक को पा सकते हैं; और एक इंडेक्स दिया गया है, आप पत्र हाथ पा सकते हैं। या, आप शब्दकोश को एक हैशमैप के रूप में संग्रहीत कर सकते हैं जो हाथ से उसके सूचकांक तक मैप करता है। सूचकांक 0 और 2598959 के बीच एक पूर्णांक है, इसलिए इसे 23 बिट्स का उपयोग करके दर्शाया जा सकता है।

यह दृष्टिकोण काम करेगा और कार्यक्रम के लिए बहुत सरल होगा, लेकिन यह अंतरिक्ष में बेकार है (कार्यक्रम निष्पादन का आकार)।

रैंकिंग / unranking

वैकल्पिक रूप से, यदि आप देखभाल करते हैं, तो बेहतर तरीके हैं। देखें, उदाहरण के लिए, निम्नलिखित में से कोई भी संदर्भ:

सामान्य विषय को "संयोजनों की रैंकिंग (और अनुत्तरदायी)" के रूप में जाना जाता है। ये लागू करने और समझने के लिए थोड़े अधिक जटिल हैं, लेकिन कार्यक्रम में एक हार्ड-कोडेड शब्दकोश को शामिल करने की आवश्यकता से बचें।


मैं सवाल अपडेट करूंगा। हां 2598960 हाथ हैं। शब्दकोश में कई पंक्तियाँ होंगी। मेरी समस्या कुंजी की पीढ़ी है। 5 कार्ड से मुझे शब्दकोश देखने के लिए एक कुंजी उत्पन्न करनी होगी।
पापाराज़ो

@Paparazzi, यदि आप दृष्टिकोण शब्दकोश का उपयोग करें, हाथ है कुंजी। दूसरे शब्दों में, कुंजी हाथ में कार्डों का 5-टपल है (क्रमबद्ध क्रम में)। शब्दकोश को कुंजी के रूप में उपयोग करके हैशटेबल के रूप में संग्रहीत किया जा सकता है। यदि आपको किसी शब्दकोश की मेमोरी लागत पसंद नहीं है, तो वैकल्पिक दृष्टिकोण का उपयोग करें: रैंकिंग / अनरैंकिंग।
डीडब्ल्यू

हाँ मुझे पता है कि अगर मैं छाँटूँ तो मुझे 30 बिट्स की चाबी मिल सकती है। मैं सोच रहा था कि क्या कोई तरीका है कि आप 32 बिट्स प्राप्त कर सकते हैं या 5 कार्ड टपल को छांटे बिना। मैं रैंक और रैंकिंग में देखूंगा।
पापाराज़ो

मैं रैंकिंग का पालन नहीं करता / करती हूं, लेकिन धन्यवाद। मैं कोशिश करूंगा और इसका पता लगाऊंगा। साथ ही संबंधों की संभावनाएं भी हैं। बहुत सारे संबंध हैं।
पापाराज़ो

1
इसके अलावा प्रासंगिक: cs.stackexchange.com/questions/67664/…
छद्मनाम

3

आप पाँच वस्तुओं को सॉर्ट कर सकते हैं और साथ ही साथ कुछ प्रोसेसर पर किसी भी तुलना के बिना डुप्लिकेट के लिए जाँच कर सकते हैं: मान लें कि एक प्रोसेसर में एक तेज़ निर्देश है जो उच्चतम बिट सेट की स्थिति निर्धारित करता है, और एक तेज़ निर्देश केवल n-th बिट सेट के साथ एक संख्या की गणना करता है ।

चलिए बिट (n) बिल्कुल n-th बिट सेट के साथ संख्या है। बता दें कि उच्चतम_बिट (x) संख्या का उच्चतम बिट है जो x में सेट है, अनिर्दिष्ट मूल्य के साथ यदि x = 0. Let x ^ y एक्सक्लूसिव-या x और y हो।

दिए गए हैं, पांच नंबर ए, बी, सी, डी और ई, प्रत्येक ० से ५१ तक, हाथ में पांच कार्ड का प्रतिनिधित्व करते हैं।

आज्ञा देना x = बिट (ए) ^ बिट (बी) ^ बिट (सी) ^ बिट (डी) ^ बिट (ई)।

A = उच्चतम_बिट (x), x को x ^ बिट (A) में बदलें।

B = उच्चतम_बिट (x), x को x ^ बिट (B) में बदलें।

C = उच्चतम_बिट (x), x को x ^ बिट (C) में बदलें।

D = उच्चतम_बिट (x), x को x ^ बिट (D) में बदलें।

E = उच्चतम_बिट (x) दें।

यदि x = 0 तो संख्याओं में डुप्लिकेट थे a, b, c, d, और e। अन्यथा, ए * बिट (24) + बी * बिट (18) + सी * बिट (12) + डी * बिट (6) + ई को हाथ के एन्कोडिंग के रूप में उपयोग करें, जहां ए, बी, सी, डी और ई हैं। ऊपर बताया गया है। यह एक हाथ को 30-बिट स्ट्रिंग के रूप में एन्कोड करता है, जबकि बहुत कुशल तरीके से छंटनी करता है।


क्या यह 52 बिट्स का उपयोग करता है?
पापाराज़ो

@Paparazzi, नहीं। अंतिम पैराग्राफ पर एक और नज़र डालें। मैंने इसे और अधिक स्पष्टता प्रदान करने का प्रयास करने के लिए संपादित किया।
DW

1
इसके लिए 64-बिट सीपीयू की आवश्यकता होती है, लेकिन अंतिम परिणाम केवल 30 बिट्स का होता है।
युवल फिल्मस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.