เป็นตัวแทนไพ่โป๊กเกอร์ 5 ใบ


11

สำรับไพ่ 52 ใบไพ่ 1 ใบจากไพ่ 52 ใบ (ไม่สามารถซ้ำกันได้)

จำนวนบิตน้อยที่สุดในการแสดงไพ่ 5 ใบและอย่างไร
มือไม่ได้เรียงตามลำดับ (KQ = QK) 64329 = 96432

ใช่สามารถใช้ 52 บิต ที่สามารถแสดงไพ่ในมือจำนวนเท่าใดก็ได้

ให้ไพ่หนึ่งใบมี 5 ใบมีวิธีแสดงว่ามีน้อยกว่า 52 บิต

บัตรเดียวสามารถแสดงด้วย 6 บิต = 64 ดังนั้นสามารถใช้ 6 บิต * 5 ใบ = 30 บิต แต่นั่นจะขึ้นอยู่กับการสั่งซื้อ ฉันสามารถเรียงลำดับและสิ่งนี้จะทำงาน หากไม่ได้ผลโปรดแจ้งให้เราทราบ

มีวิธีรับคีย์เป็น 32 บิตหรือต่ำกว่าและไม่ต้องเรียง 5 tuple การ์ด

นี่สำหรับการจำลองโป๊กเกอร์และการเรียงลำดับจะเป็นค่าใช้จ่ายจำนวนมากเมื่อเทียบกับการสร้างมือ ถ้าฉันมีพจนานุกรมที่มีค่าสัมพัทธ์ของแต่ละมือมันเป็นการค้นหาสองอย่างง่าย ๆ และการเปรียบเทียบเพื่อเปรียบเทียบค่าของสองมือ ถ้าฉันต้องเรียงมือก่อนนั้นมีขนาดใหญ่เมื่อเทียบกับการค้นหาสองรายการและการเปรียบเทียบ ในการจำลองจะเปรียบเทียบล้าน ฉันจะไม่ได้รับการเรียงลำดับมือจากการจำลอง การเรียงลำดับนั้นไม่ง่ายเช่น 52 51 50 49 48 ก่อนที่ 52 51 50 49 47 คุณสามารถมีล่ามตรงได้ ....

มีมือไพ่ 5 ใบที่เป็นไปได้ 2598960 นั่นคือจำนวนแถว กุญแจสำคัญคือไพ่ 5 ใบ ฉันต้องการรับคีย์ที่มีขนาด 32 บิตหรือต่ำกว่าซึ่งไม่จำเป็นต้องเรียงลำดับการ์ดก่อน

ไม่สามารถเรียงลำดับรายการได้เท่าที่ผูกมือกัน สูทคือพลั่วคลับเพชรและหัวใจ 7c 8c 2d 3d 4s = 7s 8s 2c 3c 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 ซึ่งอาจเร็วกว่าฟังก์ชันไลบรารีที่คุณกำลังใช้อยู่
Yuval Filmus

1
ผมไม่เข้าใจว่าทำไมคุณพูดว่า"เรียงลำดับไม่ง่าย" การเรียงลำดับนั้นง่าย - แปลงไพ่แต่ละใบให้มีจำนวนตั้งแต่ 1 ถึง 52 เพื่อให้มือแสดงด้วยรายการ (ความยาว 5) ของไพ่ เรียงรายการนั้น นั่นเป็นเพียงปัญหาของการเรียงลำดับรายการจำนวนเต็ม 5 ตัวซึ่งสามารถทำได้เร็วมากดังที่ Yuval กล่าวถึง ฉันขอแนะนำให้คุณวัดก่อนที่จะสมมติว่าช้าเกินไป แต่ฉันเดาว่าการเรียงลำดับรายการดังกล่าวจะเร็วมากและอาจเร็วกว่าหน่วยความจำเข้าถึงโดยสุ่มซึ่งไม่ได้อ่านในแคช
DW

@dw ใช่การจัดเรียงนั้นง่าย แต่สิ่งที่ฉันทำ (ล้านครั้ง) นั้นง่าย ฉันทดสอบและเรียงลำดับสองเท่าในเวลา
paparazzo

1
@Pararazzi ไม่ Yuval กำลังบอกให้คุณเขียนชุดการเรียงลำดับของคุณเองซึ่งได้รับการปรับแต่งโดยเฉพาะเพื่อจัดเรียงห้าตัวเลขระหว่าง 1 ถึง 52 คุณลองใช้ไลบรารีรูทีนซึ่งช้ากว่าเพราะมันเป็นเรื่องทั่วไปมากกว่าและเพราะธรรมชาติแบบเรียกซ้ำ ของ quicksort ทำให้ไม่มีประสิทธิภาพมากในรายการสั้น ๆ
David Richerby

ในทางปฏิบัติรายการส่วนใหญ่ที่ไม่ใช่ <= 16 บิตอาจเป็น 32 บิต ดังนั้นเมื่อคุณต้องการอย่างน้อย 23 บิตการเข้ารหัสใด ๆ ที่ใช้ <= 32 บิตอาจเป็นไปได้ การเข้ารหัส 6 บิตต่อการ์ด * 5 การ์ดทำงานได้ดีพอ มีหนึ่ง caveat: ดัชนีอาเรย์ 23 บิตดีกว่าดัชนีอาเรย์ 32 บิตมาก
MSalters

คำตอบ:


10

ให้เป็น[ 52 , 25 , 11 ]รหัส เมทริกซ์ความเท่าเทียมกันของการตรวจสอบCเป็น27 × 52เมทริกซ์บิตดังกล่าวว่าจำนวนที่น้อยที่สุดของคอลัมน์ที่มีแฮคเกอร์หายไปเป็น11 แสดงถึง52คอลัมน์โดย1 , ... , 52 เราสามารถระบุแต่ละA iเป็นเลขฐานสองที่มีความยาว27บิต คำมั่นสัญญาก็คือ XOR ของ1ถึง10ของตัวเลขเหล่านี้จะไม่เป็น0[52,25,11]27×521152A1,...,A52Aผม271100a,,,d,อีAaAAAdAอีH1,H210-2|H1H2|10

Bob Jenkins อธิบายรหัสดังกล่าวในเว็บไซต์ของเขาและจากนั้นเราสามารถแยกอาร์เรย์

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 เวกเตอร์แรกเป็นเพียง 27 หมายเลขของน้ำหนักแฮมมิง 1 เพื่อตรวจสอบว่าการก่อสร้างนี้ถูกต้องพอเพียงที่จะต้องพิจารณาทั้งหมดเป็นไปได้ที่ไม่น่าสนใจรวมกันของตัวเลข 25 ตัวสุดท้าย ตรวจสอบว่า XOR ของพวกเขามีน้ำหนักแฮมมิงอย่างน้อย 10 ตัวอย่างเช่นหมายเลขแรกสุดที่ 0x07fe0000 มีน้ำหนักแฮมมิ่งเท่ากับ 10252-27-1=225-1


ฉันไม่ทำตาม ต้องใช้มือกี่บิต?
paparazzo

ต้องการ 27 บิต คุณสามารถใช้จำนวนบิตที่มากขึ้น
Yuval Filmus

ขอบคุณ ฉันทดสอบและตัวเลขนั้นไม่เหมือนใครและ <= 32 บิต ฉันสามารถหาไพ่ 5 ใบจากหมายเลขได้หรือไม่? ถ้าไม่ดีก็แค่ถาม
paparazzo

ใช่มันเป็นพีชคณิตเชิงเส้นอย่างง่าย คุณสามารถใช้เมทริกซ์ที่ถูกต้องเพื่อกลับเวกเตอร์ที่มีความยาว 52 กับ 5 อัน ฉันจะให้คุณคิดออก
Yuval Filmus

13

nLGnLG2598960=22

การเป็นตัวแทนทำงานอย่างไร มีตัวเลือกต่าง ๆ ที่มีการแลกเปลี่ยนที่แตกต่างกัน ฉันรายการที่สองด้านล่าง

พจนานุกรมฮาร์ดโค้ด

ในกรณีนี้จำนวนไพ่ 5 ใบที่เป็นไปได้มีขนาดเล็กพอที่คุณจะมีพจนานุกรมที่มีรหัสตายตัวซึ่งแสดงรายการไพ่ทั้งหมด 2598960 แฮนด์และคุณเป็นตัวแทนดัชนีด้วยมือในพจนานุกรม (แสดงเป็นไบนารี)

กล่าวอีกนัยหนึ่งพจนานุกรมสามารถเรียงลำดับมือได้ แต่ละมือคือไพ่ 5 ใบในมือเรียงตามลำดับ คุณสามารถค้นหามือในพจนานุกรมโดยใช้การค้นหาแบบไบนารีและค้นหาดัชนีที่เกี่ยวข้อง และรับดัชนีคุณสามารถค้นหามือที่สอดคล้องกัน หรือคุณสามารถจัดเก็บพจนานุกรมเป็น hashmap ที่จับคู่จากมือกับดัชนี ดัชนีเป็นจำนวนเต็มระหว่าง 0 ถึง 2598959 ดังนั้นจึงสามารถแสดงด้วย 23 บิต

วิธีการนี้จะทำงานและเขียนโปรแกรมได้ง่าย แต่ก็สิ้นเปลืองเนื้อที่ (ขนาดของโปรแกรมที่สามารถเรียกทำงานได้)

การจัดอันดับ / unranking

หรือถ้าคุณใส่ใจมีวิธีที่ดีกว่า ดูเช่นการอ้างอิงใด ๆ ต่อไปนี้:

หัวข้อทั่วไปเรียกว่า "การจัดอันดับ (และยกเลิกการจัดเรียง) ชุดค่าผสม" สิ่งเหล่านี้ซับซ้อนกว่าเล็กน้อยในการติดตั้งและทำความเข้าใจ แต่หลีกเลี่ยงความจำเป็นที่จะต้องรวมพจนานุกรมที่มีรหัสตายตัวในโปรแกรม


ฉันจะอัปเดตคำถาม ใช่มีมือ 2598960 พจนานุกรมจะมีหลายแถว ปัญหาของฉันคือการสร้างกุญแจ จาก 5 ใบฉันต้องสร้างกุญแจเพื่อทำการค้นหาพจนานุกรม
paparazzo

@Pararazzi ถ้าคุณใช้วิธีพจนานุกรมมือเป็นกุญแจสำคัญ กล่าวอีกนัยหนึ่งที่สำคัญคือ 5-tuple ของการ์ดในมือ (เรียงตามลำดับ) พจนานุกรมสามารถจัดเก็บเป็น hashtable โดยใช้เป็นคีย์ หากคุณไม่ชอบค่าใช้จ่ายหน่วยความจำของพจนานุกรมให้ใช้วิธีทางเลือก: การจัดอันดับ / ยกเลิกการจัดเรียง
DW

ใช่ฉันรู้ว่าฉันจะได้รับกุญแจ 30 บิตถ้าฉันเรียงลำดับ ฉันสงสัยว่าถ้ามีวิธีรับคีย์ 32 บิตหรือต่ำกว่าโดยไม่ต้องคัดแยก 5 การ์ด tuple ฉันจะดูอันดับและอันดับ
paparazzo

ฉันไม่ได้ติดตามการจัดอันดับ / ไม่ได้จัดอันดับ แต่ขอขอบคุณ ฉันจะลองและคิดออก ยังมีความเป็นไปได้ของความสัมพันธ์ มีความสัมพันธ์มากมาย
paparazzo

1
มีความเกี่ยวข้องด้วย: cs.stackexchange.com/questions/67664/…
นามแฝง

3

คุณสามารถเรียงลำดับห้ารายการและตรวจสอบรายการซ้ำพร้อมกันโดยไม่มีการเปรียบเทียบกับโปรเซสเซอร์บางตัว: สมมติว่าโปรเซสเซอร์มีคำสั่งที่รวดเร็วซึ่งกำหนดตำแหน่งของชุดบิตสูงสุดและคำแนะนำอย่างรวดเร็วคำนวณตัวเลขด้วยชุดบิต n-th เท่านั้น .

ให้ bit (n) เป็นตัวเลขที่มีการตั้งค่าบิต n-th อย่างแน่นอน ให้ maximum_bit (x) เป็นจำนวนบิตสูงสุดที่ตั้งไว้ในจำนวน x โดยมีค่าที่ไม่ระบุหาก x = 0 ให้ x ^ y เป็นเอกสิทธิ์ของ x และ y

รับคือห้าหมายเลข a, b, c, d และ e แต่ละค่าจาก 0 ถึง 51 แสดงถึงไพ่ห้าใบในมือ

ให้ x = บิต (a) ^ bit (b) ^ bit (c) ^ bit (d) ^ bit (e)

ให้ A = maximum_bit (x), เปลี่ยน x เป็น x ^ บิต (A)

ให้ B = maximum_bit (x), เปลี่ยน x เป็น x ^ บิต (B)

ให้ C = maximum_bit (x), เปลี่ยน x เป็น x ^ บิต (C)

ให้ D = maximum_bit (x), เปลี่ยน x เป็น x ^ บิต (D)

ให้ E = maximum_bit (x)

ถ้า x = 0 จะมีการซ้ำซ้อนใน ns, a, b, c, d และ e มิฉะนั้นให้ใช้ A * บิต (24) + B * บิต (18) + C * บิต (12) + D * บิต (6) + E เป็นการเข้ารหัสของมือโดยที่ A, B, C, D และ E กำหนดไว้ข้างต้น สิ่งนี้เข้ารหัสมือเป็นสตริง 30 บิตในขณะที่ทำการเรียงลำดับด้วยวิธีที่มีประสิทธิภาพมาก


สิ่งนี้ใช้ 52 บิตหรือไม่
paparazzo

@Pararazzi ไม่ ลองดูอีกวรรคหนึ่ง ฉันแก้ไขเพื่อพยายามให้ความคมชัดยิ่งขึ้น
DW

1
ต้องใช้ CPU 64 บิต แต่ผลลัพธ์ที่ได้คือ 30 บิตเท่านั้น
Yuval Filmus
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.