เลือกไพ่ใบสุดท้ายในมือโป๊กเกอร์


31

มือโป๊กเกอร์นั้นถูกจัดอันดับจากดีที่สุดถึงแย่ที่สุดดังนี้:

  1. Straight flush - ไพ่ห้าใบเรียงตามลำดับทั้งหมดในชุดเดียวกัน
  2. ไพ่สี่ใบในประเภทเดียวกัน - ไพ่สี่ใบที่มีแต้มเท่ากันและไพ่หนึ่งใบที่มีลำดับอื่น
  3. ฟูลเฮาส์ - ไพ่สามใบในหนึ่งอันดับและไพ่สองใบในอีกอันดับหนึ่ง
  4. Flush - ไพ่ห้าใบในชุดเดียวกันทั้งหมด
  5. เส้นตรง - ไพ่ห้าใบเรียงตามลำดับ
  6. ไพ่ชนิดเดียวกันสามใบ - ไพ่สามใบที่มีแต้มเท่ากันและไพ่สองใบที่มีสองแถว
  7. สองคู่ - ไพ่สองใบในลำดับเดียวกันไพ่สองใบในลำดับอื่นและไพ่หนึ่งใบในลำดับที่สาม
  8. หนึ่งคู่ - ไพ่สองใบที่มีแต้มเท่ากันและไพ่สามใบที่มีสามแถวอื่น ๆ
  9. ไพ่สูง - ไพ่ห้าใบไม่เรียงตามลำดับหรือชุดเดียวกันทั้งหมดและไม่มีไพ่ใดในลำดับเดียวกัน

  • อันดับ = จำนวนบนการ์ด (A, K, Q, J, 10, 9, 8, 7, 6, 5, 4, 3, 2) คุณอาจเลือกใช้ T แทน 10
  • ชุดสูท = หัวใจ (h), โพดำ (s), คลับ (c) และเพชร (d)

โปรดทราบว่า Ace Aสามารถเป็นจำนวนสูงสุดและต่ำสุด (1 หรือ 14)

บัตรสามารถระบุได้ด้วยตัวอักษรสองตัวAs(Ace of Spades), Jc(Jack of Clubs), 7h(7 ดวง) และอื่น ๆ


ท้าทาย:

คุณได้รับไพ่สี่ใบจากตัวแทนจำหน่าย (สี่สายอินพุต) ค้นหาและเอาท์พุทการ์ดใบสุดท้ายที่ดีที่สุดเท่าที่จะเป็นไปได้

หากมีการ์ดที่ดีเท่า ๆ กันคุณสามารถเลือกได้

input และ output รูปแบบที่เป็นตัวเลือก แต่การ์ดแต่ละใบจะต้องระบุว่าเป็นที่ปรากฏข้างต้นและJc2h


กรณีทดสอบ:

Ah Kh Jh 10h
Qh

7d 8h 10c Jd
9d (or 9h, 9c, 9s)

Js 6c 10s 8h
Jc (or Jh, Jd)

Ac 4c 5d 3d
2h (or 2d, 2c, 2s)

5s 9s Js As
Ks

2h 3h 4h 5h
6h

Js Jc Ac Ah
As (or Ad)  <- Note that AAAJJ is better than AAJJJ because A is higher than J

10d 9d 5h 9c
9h (or 9s)

Ah Ac Ad As
Ks (or Kd, Kh, Kc)

4d 5h 8c Jd
Jc (or Js, Jh)

นี่คือรหัสกอล์ฟดังนั้นการส่งที่สั้นที่สุดในหน่วยไบต์จะชนะ

คำตอบ:


13

Pyth, 73 ไบต์

eo_S+*-5l@\AN}SPMJ+NZSM.:+\AT5+-4l{eMJlM.gPkJ-sM*=T+`M}2Tc4"JQKA""hscd"=Zc

นี่มันแย่มาก การแยกไพ่การเรียงลำดับค่า ... ทุกสิ่งต้องใช้ตัวอักษรจำนวนมาก แต่วิธีการนั้นน่าสนใจ

ลองใช้ออนไลน์: การสาธิตหรือชุดทดสอบ

คำอธิบาย:

ฉันสร้างไพ่ทั้งหมด 52 ใบลบไพ่สี่ใบของอินพุตสร้างคะแนนสำหรับการ์ดแต่ละใบ (คะแนนของมือ) และพิมพ์การ์ดด้วยคะแนนสูงสุด

คะแนนเป็นสิ่งที่แปลกเล็กน้อย หากฉันเปรียบเทียบคะแนนของมือทั้งสองที่แตกต่างกันอย่างสิ้นเชิงมันอาจเลือกผู้ชนะที่ผิด เช่นตรงจะชนะ 4 เอซ แต่มันใช้ได้ผลถ้าไพ่ 4 ใบแรกเหมือนกันในมือทั้งสองข้าง และคะแนนการคำนวณของฉันไม่ใช่ค่าจริง แต่เป็นรายการค่า:

  • G: ครั้งแรกฉันจัดกลุ่มไพ่ 5 ใบตามลำดับและทำตามความยาว: 5h 5d 6c 5s Jd -> [3, 1, 1]
  • F: จากนั้นฉันจะเพิ่ม 4 ชุดด้วยจำนวนห้องชุดที่ต่างกันในรายการนี้ Flush -> 3ได้รับการต่อท้ายnot flush -> 2/1/0ได้รับการต่อท้าย
  • S: เพิ่มหมายเลขอื่น 0ถ้ามันไม่ตรง4ถ้ามันเป็นเส้นตรงA2345หรือ5ถ้ามันเป็นเส้นตรงที่สูงกว่า

รายการหมายเลข 4-7 เหล่านี้จะเรียงลำดับตามลำดับที่ลดลงและเลือกรายการที่มีค่าสูงสุด

ทำไมจึงใช้งานได้ ที่นี่คุณจะเห็นการกำหนดค่าที่เป็นไปได้สำหรับทุกประเภท ตัวอักษรข้างตัวเลขบอกคุณว่ากฎนี้สร้างตัวเลขอะไร

  • ล้างตรง: [5S, 3F, 1G, 1G, 1G, 1G, 1G]หรือ[4S, 3F, 1G, 1G, 1G, 1G, 1G]
  • สี่ชนิด: [4G, 1G, 0F, 0S]
  • บ้านเต็ม: [3G, 2G, 1F, 0S]หรือ[3G, 2G, 0F, 0S]
  • ฟลัช: [3F, 1G, 1G, 1G, 1G, 1G, 0S]
  • ตรง: [5S, 2F, 1G, 1G, 1G, 1G, 1G], [5S, 1F, 1G, 1G, 1G, 1G, 1G], [5S, 1G, 1G, 1G, 1G, 1G, 0F], [4S, 2F, 1G, 1G, 1G, 1G, 1G],[4S, 1F, 1G, 1G, 1G, 1G, 1G] ,[4S, 1G, 1G, 1G, 1G, 1G, 0F]
  • สามชนิด: [3G, 1G, 1G, 1F, 0S] ,[3G, 1G, 1G, 0F, 0S]
  • สองคู่: [2G, 2G, 2F, 1G, 0S],[2G, 2G, 1F, 1G, 0S] ,[2G, 2G, 1G, 0F, 0S]
  • หนึ่งคู่: [2G, 2F, 1G, 1G, 1G, 0S],[2G, 1G, 1G, 1G, 1F, 0S] ,[2G, 1G, 1G, 1G, 0F, 0S]
  • บัตรสูง: [2F, 1G, 1G, 1G, 1G, 1G, 0S], [1F, 1G, 1G, 1G, 1G, 1G, 0S],[1G, 1G, 1G, 1G, 1G, 0S, 0F]

Pyth เปรียบเทียบรายการที่ชาญฉลาด ดังนั้นจึงเห็นได้ชัดว่า Straight flush จะชนะสี่ชนิดเสมอ กฎทั่วไปของโป๊กเกอร์ส่วนใหญ่มีความชัดเจนกับรายการเหล่านี้ บางคนดูเหมือนจะขัดแย้งกัน

  • สเตรทจะชนะต่อสี่แบบหรือเต็มบ้าน: ไม่ใช่ปัญหา หากคุณมีโอกาสได้บ้านสี่หลัง / บ้านเต็มรูปแบบพร้อมการ์ดแม่น้ำกว่าที่คุณไม่สามารถติดต่อได้ในเวลาเดียวกัน (เนื่องจากคุณมีห้องชุดที่แตกต่างกัน 2 หรือ 3 ห้องในมือของคุณ)
  • สเตรจจะชนะเมื่อเทียบกับฟลัช หากคุณสามารถเข้าถึงฟลัชและตรงด้วยบัตรริเวอร์แล้วคุณยังสามารถเข้าถึงฟลัชตรง และฟลัชแบบตรงมีคะแนนดีกว่าทั้งแบบสเตรทและฟลัช
  • คู่หนึ่ง[2G, 2F, 1G, 1G, 1G, 0S]จะชนะเมื่อเทียบกับมือทั้งสองคู่ ยังไม่มีปัญหา หากคุณได้รับไพ่สองใบที่มีริเวอร์การ์ดกว่าที่คุณมีอย่างน้อยหนึ่งคู่ก่อนที่ริเวอร์ แต่นั่นหมายความว่าคุณสามารถปรับปรุงเป็นสามประเภทซึ่งดีกว่า ดังนั้นสองคู่จะไม่มีคำตอบจริงๆ
  • ไพ่สูง[2F, 1G, 1G, 1G, 1G, 1G, 0S]จะชนะต่อมือคู่หนึ่ง ถ้านี่เป็นคะแนนที่ดีที่สุดที่คุณสามารถไปถึงได้ก่อนแม่น้ำคุณจะมีไพ่ 3 ใบในหนึ่งชุดและไพ่หนึ่งใบในชุดที่แตกต่างกัน แต่จากนั้นคุณสามารถเลือกบัตรที่มีหนึ่งในสองห้องชุดเหล่านี้และมีมูลค่าที่ปรากฏอยู่แล้วและคุณจะจบลงด้วยคะแนน[2F, 2G, ...]ซึ่งก็ดีกว่าเช่นกัน

ดังนั้นนี่เป็นการเลือกประเภทของการแก้ปัญหาที่ถูกต้อง แต่ฉันจะได้รับหนึ่งคู่ที่ดีที่สุด (จาก 4 ความเป็นไปได้) ฉันจะเลือกตรงที่ดีที่สุดได้อย่างไร ... ? เนื่องจากโซลูชันหนึ่งคู่ที่ต่างกันสองรายการสามารถมีคะแนนเท่ากัน

ง่ายมาก Pyth รับประกันการจัดเรียงที่เสถียร (เมื่อถ่ายสูงสุด) 2h 2s 2c 2d 3h 3s ... Adดังนั้นผมจึงง่ายสร้างการ์ดในการสั่งซื้อ ดังนั้นการ์ดที่มีค่าสูงสุดจะเป็นจำนวนสูงสุดโดยอัตโนมัติ

รายละเอียดการใช้งาน

=ZcZแยกสายป้อนและร้านค้ารายชื่อในบัตร =T+`M}2Tc4"JQKA"สร้างรายการของการจัดอันดับและเก็บไว้ใน['2', ..., '10', 'J', 'Q', 'K', 'A'] สร้างการรวมกันของการจัดอันดับที่มีห้องสวีทแต่ละครั้งและเอาบัตรของT-sM*T..."hscd"ZZ

o...สั่งซื้อบัตรที่เหลือเหล่านี้โดย: lM.gPkJความยาวของกลุ่มของอันดับที่+-4l{eMJlMผนวกความยาว 4 (ห้องสวีท) +*-5l@\AN}SPMJ+NZSM.:+\AT5ผนวก 0/4/5 ขึ้นอยู่กับชุด (สร้างแต่ละสตริงย่อยที่มีความยาว 5 ของ "A" + T ตรวจสอบว่ามือ หนึ่งในนั้น (ต้องเรียงลำดับมือและจัดเรียงชุดย่อยทั้งหมด) คูณด้วย 5 "จำนวน" ในการ์ด) _Sเรียงลำดับรายการที่ลดลง

e เลือกสูงสุดและพิมพ์


2
คำอธิบายที่สร้างสรรค์มากและยอดเยี่ยม!
Greg Martin

4

JavaScript (ES6), 329 324 317 312 309 ไบต์

H=>[..."cdhs"].map(Y=>[...L="AKQJT98765432"].map(X=>~H.indexOf(X+=Y)||([...H,X].map(([R,S])=>a|=eval(S+'|=1<<L.search(R)',F|=S!=H[0][1]),F=a=c=d=h=s=0),x=c|d,y=h|s,c&=d,h&=s,p=c|x&y|h,t=c&y|h&x,(S=a-7681?((j=a/31)&-j)-j?F?c&h?2e4+a:t?t^p?3e4+t:7e4:p?8e4+p:M:4e4+a:F?5e4+a:a:F?6e4:1e4)<M&&(R=X,M=S))),M=1/0)&&R

มันทำงานอย่างไร

Sสำหรับแต่ละบัตรที่เหลืออยู่ในสำรับเราคำนวณคะแนนมือ ยิ่งคะแนนต่ำเท่าไหร่มือก็ยิ่งดีเท่านั้น

ตัวแปรที่ใช้ในการคำนวณคะแนน

  • F: falsy ถ้ามือนั้นเป็นสีแดง
  • c: bitmask of Clubs
  • d: bitmask of Diamonds
  • h: bitmask of Hearts
  • s: bitmask of Spades
  • x = c | d: bitmask ของ Clubs หรือ Diamonds
  • y = h | s: bitmask of Hearts OR Spades
  • a: bitmask ของชุดที่รวมกันทั้งหมด
  • p = c & d | x & y | h & s: pair bitmask (1)
  • t = c & d & y | h & s & xbitmask สามชนิด(1)

(1) ฉันเขียนสูตรเหล่านี้เมื่อหลายปีก่อนและใช้มันในเครื่องมือโป๊กเกอร์หลายรายการ พวกเขาทำงาน :-)

สูตรอื่น ๆ

  • c & d & h & s: bitmask สี่ชนิด
  • a == 7681: ทดสอบแบบตรงพิเศษ "A, 2, 3, 4, 5" (0b1111000000001)
  • ((j = a / 31) & -j) == j: ทดสอบ straights อื่น ๆ ทั้งหมด

แผนภูมิคะแนน

Value    | Hand
---------+--------------------------------------------
0   + a  | Standard Straight Flush
1e4      | Special Straight Flush "A, 2, 3, 4, 5"
2e4 + a  | Four of a Kind
3e4 + t  | Full House
4e4 + a  | Flush
5e4 + a  | Standard Straight
6e4      | Special Straight "A, 2, 3, 4, 5"
7e4      | Three of a Kind
8e4 + p  | Pair
Max.     | Everything else

หมายเหตุ:เราไม่ต้องสนใจ Two-Pair ซึ่งเป็นตัวเลือกที่ดีที่สุดของเรา (ถ้าเรามีหนึ่งคู่อยู่แล้วเราสามารถเปลี่ยนเป็นสามชนิดและถ้าเรามีสองคู่อยู่แล้วเราสามารถเปลี่ยนพวกมันเป็นฟูลเฮาส์ได้)

กรณีทดสอบ


3

JavaScript (ES6), 307 349

มันค่อนข้างใหญ่และฉันไม่แน่ใจว่ามันเป็นวิธีที่ดีที่สุด อาจจะยังเล่นกอล์ฟได้เล็กน้อย

h=>(r='_23456789TJQKAT',R=x=>r.search(x[0]),M=i=>[...'hcds'].some(s=>h.indexOf(j=h[i][0]+s)<0)&&j,[u,v,w,y]=h.sort((a,b)=>R(a)-R(b)).map(x=>R(x)),[,,d,e,f,g,k]=[...new Set(h+h)].sort(),q=10-u-v-w,s=(z=y>12)&q>0?q:y-u<5&&u*5+q-y,d>r?z?'Kh':'Ah':f>r?M((e>r?v<w:u<v)+1):s?r[s]+g:k?M(3):r[13-z-(w>11)-(v>10)]+g)

น้อย golfed

h=>(
  // card rank, 1 to 13, 0 unused
  // fake rank 14 is T, to complete a straight JQKA?
  // as I always try to complete a straight going up
  r = '_23456789TJQKAT', 

  // R: rank a card
  R = x => r.search(x[0]),  

  // M: find a missing card (to complete a same-rank set like a poker)
  // look for a card with the same rank of the card at position i
  // but with a suit not present in the hand
  M = i => [...'hcds'].some(s => h.indexOf(j=h[i][0]+s) < 0) && j,
  h.sort((a, b) => R(a)-R(b) ), // sort hand by rank
  [u,v,w,y] = h.map(x=>R(x)),   // rank of cards 0..3 in u,v,w,y

  // Purpose: look for duplicate rank and/or duplicate suits
  // Put values and suits in d,e,f,g,k, with no duplicates and sorted
  // suits are lowercase and will be at right end
  [,,d,e,f,g,k] = [...new Set(h+h)].sort(),

  // Only if all ranks are different: find the missing value to get a straight
  // or 0 if a straight cannot be obtained
  // The first part manages the A before a 2
  q = 10-u-v-w, s = y>12&q>0 ? q : y - u < 5 && u * 5 + q - y,

  d > r // d is lowercase -> all cards have the same rank
    ? u < 13 ? 'Ah' : 'Kh' // add a K to a poker of A, else add an A
    : e > r // e is lowercase -> 2 distinct ranks
      ? M(v<w ? 2 : 1) // go for a poker or a full house
      : f > r // f is lowercase -> 3 distinct ranks, we have a pair
        ? M(u<v ? 2 : 1) // find the pair and go for 3 of a kind
        : s // all different ranks, could it become a straight?
          ? r[s] + g // if there is only a suit, it will be a flush straight too
          : k // if there are 2 or more different suits
            ? M(3) // go for a pair with the max rank
            : r[13-(y>12)-(w>11)-(v>10)]+g // flush, find the max missing card
)

ทดสอบ

F=
h=>(r='_23456789TJQKAT',R=x=>r.search(x[0]),M=i=>[...'hcds'].some(s=>h.indexOf(j=h[i][0]+s)<0)&&j,[u,v,w,y]=h.sort((a,b)=>R(a)-R(b)).map(x=>R(x)),[,,d,e,f,g,k]=[...new Set(h+h)].sort(),q=10-u-v-w,s=(z=y>12)&q>0?q:y-u<5&&u*5+q-y,d>r?z?'Kh':'Ah':f>r?M((e>r?v<w:u<v)+1):s?r[s]+g:k?M(3):r[13-z-(w>11)-(v>10)]+g)

output=x=>O.textContent+=x+'\n'

;`Ah Kh Jh Th -> Qh
7d 8h Tc Jd -> 9d 9h 9c 9s
Js 6c Ts 8h -> Jc Jh Jd
Ac 4c 5d 3d -> 2h 2d 2c 2s
5s 9s Js As -> Ks
2h 3h 4h 5h -> 6h
Js Jc Ac Ah -> As Ad
Td 9d 5h 9c -> 9h 9s
Ah Ac Ad As -> Ks Kd Kh Kc
4d 5h 8c Jd -> Jc Js Jh`
.split('\n')
.forEach(s=>{
  var o = s.match(/\w+/g) // input and output
  var h = o.splice(0,4) // input in h, output in o
  var hs = h+''
  var r = F(h)
  var ok = o.some(x => x==r)
  
  output((ok?'OK ':'KO ')+ hs + ' -> ' + r)
})
<pre id=O></pre>


ตลกที่เห็นว่าทั้งสองวิธีของเราดูเหมือนจะมาบรรจบกันในขนาดที่คล้ายกันมาก :-) ประสิทธิภาพฉลาดคุณจะเร็วขึ้นแน่นอน
Arnauld

@Arnauld ฉันจัดการเพื่อโกนอีก 4 ไบต์ ตาคุณ
edc65
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.