เปรียบเทียบสองมือโป๊กเกอร์


14

ท้าทาย:

เมื่อได้ไพ่ห้าใบในมือสองใบให้ตัดสินว่าฝ่ายใดจะชนะโดยการจัดอันดับไพ่ในมือแบบมาตรฐาน

การป้อนข้อมูล:

ไพ่สิบใบคั่นด้วยช่องว่างจาก stdin หรืออาร์กิวเมนต์บรรทัดคำสั่งแล้วแต่ว่าคุณต้องการอะไร ไพ่ห้าใบแรกเป็นไพ่ของผู้เล่น 1 ในขณะที่ไพ่ห้าใบสุดท้ายเป็นไพ่ในมือของผู้เล่น 2 บัตรแต่ละใบจะเป็นสตริงตัวอักษรสองตัวของแบบฟอร์ม RS โดยที่ R คืออันดับและ S เป็นชุด อันดับอยู่ในช่วง 2-9, T สำหรับสิบและ J, Q, K และ A สำหรับ Jack, Queen, King และ Ace ตามลำดับ ชุดคือ H, D, C, S สำหรับหัวใจ, เพชร, คลับ, และโพดำตามลำดับ คุณต้องส่งออกจำนวนผู้เล่นที่ชนะ: '1' หรือ '2'

ตัวอย่างของการ์ด:

AS - the Ace of Spades
QD - the Queen of Diamonds
2C - the Two of Clubs
TH - the Ten of Hearts

ตัวอย่างอินพุต:

5H 5C 6S 7S KD 2C 3S 8S 8D TD -> 2

คำอธิบาย: ผู้เล่น 1 มีคู่ที่ห้าในขณะที่ผู้เล่น 2 มีคู่ที่แปด

5D 8C 9S JS AC 2C 5C 7D 8S QH -> 1

คำอธิบาย: ผู้เล่นทั้งสองไม่มีอะไรพิเศษ แต่การ์ดระดับสูงของผู้เล่น 1 คือเอซในขณะที่การ์ดที่สูงของผู้เล่น 2 เป็นราชินี

2D 9C AS AH AC 3D 6D 7D TD QD -> 2

คำอธิบาย: ผู้เล่น 1 มีสามเอซ, ผู้เล่น 2 มีฟลัชออฟไดมอนด์

4D 6S 9H QH QC 3D 6D 7H QD QS -> 1

คำอธิบาย: ผู้เล่นทั้งคู่มีคู่ของควีนส์ แต่การ์ดที่สูงที่สุดอันดับสองของผู้เล่น 1 คือไพ่เก้าในขณะที่ผู้เล่น 2 เป็นการ์ดเจ็ด

กฎและคำชี้แจง:

  • อ้างอิงการจัดอันดับมาตรฐานของมือโป๊กเกอร์สำหรับรายละเอียดของการเปรียบเทียบมือ
  • คุณอาจสมมติว่าไม่มีไพ่ซ้ำในแต่ละคู่
  • คุณอาจคิดว่ามีผู้ชนะแน่นอนในแต่ละกรณี
  • สูทไม่ได้คำนึงถึงการจัดอันดับของมือ ตัวอย่างเช่นรอยัลฟลัชสองชุดที่ต่างกันมีค่าเท่ากันดังนั้นข้อมูลใด ๆ ที่ผู้เล่นทั้งสองมีรอยัลฟลัชนั้นไม่ถูกต้องตามกฎก่อนหน้านี้
  • เนื่องจากนี่คือรหัสกอล์ฟคำตอบที่สั้นที่สุดชนะ

หมายเหตุ:


ขอโทษถ้ามีอะไรที่ฉันพลาดไป! นี่คือคำถามรหัสกอล์ฟครั้งแรกของฉัน
คอมมานโด

สิ่งนี้คล้ายกับคำถามล่าสุดของcodegolf.stackexchange.com/q/23743/15599และเวอร์ชัน 5 การ์ดที่อ้างอิงภายใน อย่างไรก็ตามคำถามเหล่านั้นจำเป็นต้องใช้เพื่อระบุประเภทของมือ ข้อแตกต่างที่สำคัญคือถ้าผู้เล่นทั้งสองมีมือประเภทเดียวกันเราต้องพิจารณาว่าอันดับไหนดีกว่าไพ่ (เช่นสำหรับสองคู่ที่มีคู่ที่ดีที่สุดคู่แรกคู่ที่สองและหากจำเป็นต้องใช้บัตรเดี่ยว) มันไม่ซ้ำกัน ค้นหาคำถามที่คล้ายกันเชื่อมโยงพวกเขา (ฉันเห็นว่าคุณทำ) และเตรียมพร้อมที่จะปกป้องว่าทำไมจึงไม่ซ้ำกันก่อนโพสต์
เลเวลริเวอร์เซนต์

เกิดอะไรขึ้นถ้าฟลอพและมือเหมือนกัน?
Ismael Miguel

@IsmaelMiguel ไม่มีเวอร์ชั่น flop ในเวอร์ชั่นนี้ มีเพียงสองมือแยกต่างหากที่จะต้องประเมินกับแต่ละอื่น ๆ
คอมมานโด

1
แก้ปัญหาก่อนหน้านี้สำหรับไพ่ 10 ใบ ที่นี่
Hasturkun

คำตอบ:


2

Haskell - 352 339 ตัวอักษร

import Data.List
v h=10*(sum$map(\l->l*l)g)+b g:k where
  (g,k)=unzip$reverse$sort$map(\r->(length r,head r))$group$sort$map(maybe 0 id.(`elemIndex`"23456789TJQKA").head)h
  b(1:_)=f(map(!!1)h)+t k;b _=0
f(y:z)|all(==y)z=75;f _=0
t[y,_,_,_,z]|y-z==4=70;t[12,3,2,1,0]=65;t _=0
w(a,b)|v a>v b="1\n";w _="2\n"
main=interact$w.splitAt 5.words

ทำงาน:

& echo "5H 5C 6S 7S KD 2C 3S 8S 8D TD" | runhaskell 25056-Poker.hs 
2

& echo "5D 8C 9S JS AC 2C 5C 7D 8S QH" | runhaskell 25056-Poker.hs 
1

& echo "2D 9C AS AH AC 3D 6D 7D TD QD" | runhaskell 25056-Poker.hs 
2

& echo "4D 6S 9H QH QC 3D 6D 7H QD QS" | runhaskell 25056-Poker.hs 
1

Ungolf'd และแสดงความคิดเห็นดังนั้นคุณสามารถดู techinque:

import Data.List

value :: [String] -> [Int]
value hand = 10 * (sum $ map (\l->l*l) groups) + bonus groups : kicker
    -- ^ Value of a hand is 10 times the sum of the squares of the group lengths
    -- plus the straight & flush bonus, followed by the kicker (to break ties)
    -- This 10 * sum-of-squares + bonus works out to put the hands in category
    -- order, and then they only need to be ordered by card ranks.
  where
    -- | The cards are sorted into groups by matching rank, then the groups
    -- sorted by length and rank: For example: "7C 7D 7H QS 2S" will becomes
    -- [(3,7),(1,Q),(1,2)]. This is like a run-length encoding. Finally, the
    -- groups lengths, and the kicker ranks are taken apart into two lists.
    -- N.B: kicker here includes the ranks of the groups, unlike the poker term.

    (groups,kicker) = unzip             -- split apart
        $ reverse $ sort                -- reverse sort by (length,rank)
        $ map (\r->(length r,head r))   -- turn groups into (length,rank) pairs
        $ group $ sort                  -- group sorted ranks
        $ map (maybe 0 id . (`elemIndex`"23456789TJQKA") . head) hand
            -- take first letter of each card in the hand, and map to [0..12]

    -- | Give a bonus for flush and straight to hands with five cards,
    -- or equivalently hands where the largest group length is just 1
    bonus (1:_ ) = flush (map (!!1) hand)   -- flush takes the suits of the hand
                   + straight kicker        -- straight takes the ranks
    bonus _      = 0

    -- | A flush is if all suits match the first suit
    flush (y:z) | all (==y) z = 75
                | otherwise   =  0

    -- | There are two kinds of straight.
    -- N.B: If there are five groups, then there are no duplicate ranks
    straight [y,_,_,_,z] | y-z == 4 = 70    -- normal, high to low
    straight [12,3,2,1,0]           = 65    -- ace is low, but it sorts high
    straight _                      =  0

wins :: ([String], [String]) -> String
wins (a,b) | value a > value b = "1\n"
           | otherwise         = "2\n"

main = interact $ wins . splitAt 5 . words

2

Python - 774 722 707 698 685 ตัวอักษร

import sys
t,q,e,u='--23456789TJQKA','SDCH',enumerate,len
_=lambda c,i=0:chr(97+c[i])
def j(s):
 v,g,l=[0]*15,[0]*4,''
 for c in s:
  r,s=c[0],c[1];v[t.find(r)]+=1;g[q.find(s)]+=1
 c,h,k,m,f=0,0,[0,0,[],[],[]],0,0
 for x,i in e(v):
  for b in[2,3,4]:
   if i==b:k[b]+=[x]
 v[1]=v[14]
 for x,i in e(v):
  if i:
   c+=1
   if c==5:m,h=1,x
   if i==1:l+=_([x])
  else:c=0
 f,l,d=max(g)//5*2,l[::-1],'';z=f+m
 if z==3:d='z'+l
 if k[4]:d='y'+_(k[4])+l
 if k[2] and k[3]:d='x'+_(k[3])+_(k[2])
 if z==2:d='w'+l
 if z==1:d='v'+_([h])
 if k[3]:d='u'+_(k[3])+l
 if u(k[2])>1:d='t'+_(k[2],1)+_(k[2])+l
 if u(k[2])==1>u(k[3]):d='s'+_(k[2])+l
 return d or l
p=sys.argv
print(1+(j(p[1:6])<j(p[6:])))

ฉันเลือกที่จะสร้างสตริงสำหรับแต่ละมือที่แสดงถึงมันเริ่มต้นด้วยตัวอักษรสำหรับประเภทของมือตามด้วยตัวอักษรที่อธิบายถึงรูปแบบที่เฉพาะเจาะจงของประเภท (เช่นการ์ดที่คุณเพิ่งมี 4 จาก?) ตามด้วย มูลค่าของไพ่ที่เหลือในกรณีที่เสมอกัน (หากผู้เล่นทั้งคู่มีคู่เหมือนกันไพ่ใบที่ 5 จะต้องตัดสินว่าใครชนะ) ฉันทดสอบมันค่อนข้างครอบคลุม แต่ฉันไม่ได้เล่นโป๊กเกอร์จริง ๆ ดังนั้นฉันหวังว่าจะทำให้ถูกต้อง นอกจากนี้ฉันรู้ว่ามันยังไม่ได้เล่นกอล์ฟอย่างเต็มที่ฉันอาจจะโกนทิ้งตัวละครสองสามตัวในภายหลัง


ฆ่า 5 _=lambda c:chr(97+c)ตัวอักษรด้วย นอกจากนี้คุณยังมีช่องว่างที่ไม่จำเป็นหลังจาก:s และ=s สุดท้ายใช้;แทนบรรทัดใหม่เพื่อแยกคำสั่งเพื่อลดช่องว่างที่ใช้สำหรับการเยื้อง
user12205

เป็นคนดีกับแลมบ์ดาขอบคุณ!
Tal

2

JavaScript - 526 508

function a(b){b=b.split(" ");var c=b.splice(5,5),d=[],e=[],r=[8,9,5,6,1,2,3,10,4,7],A=14,K=13,Q=12,J=11,S={"S":1,"C":2,"H":4,"D":8};for(i=0;i<5;i++){d.push(b[i].split('')[1]);b[i]=b[i].split('')[0];e.push(c[i].split('')[1]);c[i]=c[i].split('')[0]}function p(w,m){var v,i,o,s=1<<w[0]|1<<w[1]|1<<w[2]|1<<w[3]|1<<w[4];for(i=-1,v=o=0;i<5;i++,o=Math.pow(2,w[i]*4)){v+=o*((v/o&15)+1)}v=v%15-((s/(s&-s)==31)||(s==0x403c)?3:1);v-=(m[0]==(m[1]|m[2]|m[3]|m[4]))*((s==0x7c00)?-5:1);return r[v]}alert(p(b,d)>p(c,e)?1:2)}

การใช้งาน:

a("5H 5C 6S 7S KD 2C 3S 8S 8D TD");

ungolfed:

function a(b) {
b = b.split(" ");
var c=b.splice(5,5),
        d=[],
        e=[],
        r=[8,9,5,6,1,2,3,10,4,7],
        A=14,
        K=13,
        Q=12,
        J=11,
        S={"S":1,"C":2,"H":4,"D":8};

    for (i=0;i<5;i++) {
        d.push(b[i].split('')[1]);
        b[i] = b[i].split('')[0];
        e.push(c[i].split('')[1]);
        c[i] = c[i].split('')[0];   
    }

function p(w,m){
  var v, i, o, s = 1<<w[0]|1<<w[1]|1<<w[2]|1<<w[3]|1<<w[4];
  for (i=-1, v=o=0; i<5; i++, o=Math.pow(2,w[i]*4)) {v += o*((v/o&15)+1);}
  v = v % 15 - ((s/(s&-s) == 31) || (s == 0x403c) ? 3 : 1);
  v -= (m[0] == (m[1]|m[2]|m[3]|m[4])) * ((s == 0x7c00) ? -5 : 1);
  return r[v];
}

alert(p(b,d)>p(c, e)?1:2);
}

แหล่ง


1

Perl 801 733 ตัวอักษร

ฉันเชื่อว่านี่เป็นการดำเนินการที่ค่อนข้างตรงไปตรงมา โดยพื้นฐานสำหรับแต่ละมือเราเรียงชุดและใบหน้าแยกจากกัน จากนั้นเราสร้างสำเนาใบหน้าอีกอันที่มีเอซนับน้อยเพื่อให้เราสามารถตรวจสอบสเตรทที่มีเอซต่ำ จากนั้นเราตรวจสอบว่าเรามีเปี่ยมหรือตรงและสิ่งที่การ์ดสูงคือ จากนั้นเราก็ตรวจสอบการแข่งขันตามลำดับคะแนน (ก่อนอื่นเราตรวจสอบฟลัชแบบตรงแล้วก็สี่แบบ ฯลฯ ) คะแนนจริงเป็นเพียงการต่อเรียงประเภทมือตามด้วยค่าใบหน้าของไพ่ตามลำดับที่พวกเขาสำคัญ (นั่นคือ _s () ในเวอร์ชัน ungolfed, u () ในเวอร์ชัน golfed นี่มันคือ:

@l{2..9,qw(T J Q K A)}=2..14;sub u{join"",map{$_>9?$_:"0$_"}shift,ref$_[0]?$$_[0]:map{$h[$_]}@_}sub e{$p[$_[0]-1]-1==$p[$_[0]]}sub f{@p=@_;e(1)&&e(2)&&e(3)&&e 4}sub h{$h[$_[0]]==$h[$_[1]]}sub i{h(@_[0,1])&&h @_[2,3]}sub t{@s=sort map{substr($_,1)}@_;$f=$s[0]eq$s[4];@l=@h=sort{$b<=>$a}map{$l{substr($_,0,1)}}@_;@l=(@l[1..4],1)while$l[0]==14;$s=0;if(f@l){$s=1;$h=$l[0]}else{$h=$h[0];$s=1 if f@h}$f&&$s?u 9,\$h:h(4,1)?u 7,4,0:h(3,0)?u 7,3,4:i(4,3,2,0)?u 6,0,4:i(4,2,1,0)?u 6,4,0:$f?u 5,0:$s?u 4,\$h:h(4,2)?u 3,4,0,1:h(3,1)?u 3,3,0,4:h(2,0)?u 3,2..4:i(4,3,2,1)?u 2,2,4,0:i(4,3,1,0)?u 2,1,4,2:i(3,2,1,0)?u 2,1,3,4:h(4,3)?u 1,4,0,1,2:h(3,2)?u 1,3,0,1,4:h(2,1)?u 1,2,0,3,4:h(1,0)?u 1,1..4:u 0,0..4}print t(@ARGV[0..4])gt t(@ARGV[5..9])?1:2

และนี่คือสิ่งที่เทียบเท่ากับนักกอล์ฟน้อยกว่า:

use strict;
use warnings;

# ace high or low in straights, otherwise high
# T = ten, J = jack, Q = queen, K = king, A = ace

# 0 high card
# 1 one pair
# 2 two pair
# 3 3 of a kind
# 4 straight
# 5 flush
# 6 full house
# 7 four of a kind
# 9 straight flush (royal flush a subclass of straight flush)

my %l;@l{2..9,qw(T J Q K A)}=2..14;
sub score {
  my @suits = sort map { substr($_,1) } @_;
  my @faces_h = sort { $b <=> $a } map { $l{substr($_,0,1)} } @_;
  my @faces_l = @faces_h;
  @faces_l = (@faces_l[1..4], 1) while $faces_l[0] eq 14;
  my $is_flush = $suits[0] eq $suits[4];
  my ($is_straight, $high_card);
  if($faces_l[0]-1==$faces_l[1] &&
     $faces_l[1]-1==$faces_l[2] &&
     $faces_l[2]-1==$faces_l[3] &&
     $faces_l[3]-1==$faces_l[4]) {
    $is_straight=1;
    $high_card = $faces_l[0];
  } else {
    $high_card = $faces_h[0];
    if($faces_h[0]-1==$faces_h[1] &&
       $faces_h[1]-1==$faces_h[2] &&
       $faces_h[2]-1==$faces_h[3] &&
       $faces_h[3]-1==$faces_h[4]) {
      $is_straight=1;
    }
  }
  return _s(9, \$high_card) if $is_flush && $is_straight;
  return _s(7, 4,0) if $faces_h[4] == $faces_h[1];
  return _s(7, 3,4) if $faces_h[3] == $faces_h[0];
  return _s(6, 0,4) if $faces_h[4] == $faces_h[3] && $faces_h[2] == $faces_h[0];
  return _s(6, 4,0) if $faces_h[4] == $faces_h[2] && $faces_h[1] == $faces_h[0];
  return _s(5, 0) if $is_flush;
  return _s(4, \$high_card) if $is_straight;
  return _s(3, 4,0,1) if $faces_h[4] == $faces_h[2];
  return _s(3, 3,0,4) if $faces_h[3] == $faces_h[1];
  return _s(3, 2,3,4) if $faces_h[2] == $faces_h[0];
  return _s(2, 2,4,0) if $faces_h[4] == $faces_h[3] && $faces_h[2] == $faces_h[1];
  return _s(2, 1,4,2) if $faces_h[4] == $faces_h[3] && $faces_h[1] == $faces_h[0];
  return _s(2, 1,3,4) if $faces_h[3] == $faces_h[2] && $faces_h[1] == $faces_h[0];
  return _s(1, 4,0,1,2) if $faces_h[4] == $faces_h[3];
  return _s(1, 3,0,1,4) if $faces_h[3] == $faces_h[2];
  return _s(1, 2,0,3,4) if $faces_h[2] == $faces_h[1];
  return _s(1, 1,2,3,4) if $faces_h[1] == $faces_h[0];
  return _s(0, 0..4);
}

sub _s {
  join "", map { $_ > 9 ? $_ : "0$_" } shift,
    ref $_[0] ? $$_[0] : map { $faces_h[$_] } @_
  # my @a=@_;
  #  if(ref $a[1]) {
  #    $a[1]=${$a[1]};
  #  } else {
  #    $a[$_]=$faces_h[$a[$_]] for 1..$#a;
  #  }
  #  join "", map { $_ < 10 ? "0$_" : $_ } @a;
}

my @p1 = @ARGV[0..4];
my @p2 = @ARGV[5..9];

my $s1 = score(@p1);
my $s2 = score(@p2);
print $s1 gt $s2 ? 1 : 2;

AH 2C 3S 4S 5D 6C 7S 7C 7D TDก่อให้เกิดผลลัพธ์ของ2แต่ฉันคิดว่าเต้นตรงสามชนิด
r3mainer
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.