두 포커 핸드 비교


14

도전:

5 장의 패가 2 개 주어지면, 포커 패의 표준 순위로 어느 쪽이 이길 지 결정하십시오 .

입력:

stdin에서 공백으로 구분되거나 명령 행 인수로 분리 된 10 개의 카드 중 원하는 것을 선택하십시오. 처음 5 장의 카드는 1 번 선수의 손이고 마지막 5 장의 카드는 2 번 선수의 손입니다. 각 카드는 RS 형식의 두 글자 문자열이며 여기서 R은 순위이고 S는 적합합니다. 순위는 각각 2-9, T는 10, 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 번 선수는 5 쌍이며 8 번 선수는 8 쌍입니다.

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에는 에이스 3 개가 있고 플레이어 2에는 다이아몬드 플러시가 있습니다.

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

설명 : 두 선수 모두 한 쌍의 퀸즈를 가지고 있지만 2 번 선수는 7 인 반면 1 번 선수의 두 번째로 높은 카드는 9입니다.

규칙 및 설명 :

  • 비교에 대한 자세한 내용은 포커 손표준 순위를 참조하십시오 .
  • 각 핸드 페어에 반복되는 카드가 없다고 가정 할 수 있습니다.
  • 각 경우에 확실한 승자가 있다고 가정 할 수 있습니다.
  • 소송은 손의 순위에 영향을 미치지 않습니다. 예를 들어, 다른 수트의 두 번의 로얄 플러시가 동일합니다 (따라서 두 플레이어가 모두 로얄 플러시를 갖는 입력은 이전 규칙에 의해 유효하지 않습니다).
  • 이것이 코드 골프이기 때문에 가장 짧은 대답이 이깁니다.

노트:


내가 놓친 것이 있으면 사과드립니다! 이것은 내 첫 번째 코드 골프 질문입니다.
특공대

이것은이 최근 질문 codegolf.stackexchange.com/q/23743/15599 및 그 안에 참조 된 5 카드 버전과 유사 합니다. 그러나 이러한 질문은 손의 유형을 지정하는 데만 필요했습니다. 여기서 가장 큰 차이점은 두 선수가 같은 유형의 핸드를 가지고 있다면, 우리는 카드 순위에 따라 더 좋은 카드를 결정해야한다는 것입니다 (예 : 두 페어, 가장 좋은 페어를 가진 두 페어, 필요한 경우 싱글 카드). 중복되지 않습니다. 항상 비슷한 질문을 검색하고 연결 한 다음 (본적이 있습니다) 게시하기 전에 중복되지 않은 이유를 방어 할 준비를하십시오.
Level River St

플롭과 손이 같은 경우 어떻게해야합니까?
Ismael Miguel

@IsmaelMiguel이 버전에는 플롭이 없습니다. 서로에 대해 평가해야하는 두 개의 분리 된 손이 있습니다.
특공대

1
이전 10 개 카드를 해결 여기
Hasturkun

답변:


2

하스켈 - (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하고 댓글을 달았으므로 기술 정보를 볼 수 있습니다.

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

파이썬 - 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

자바 스크립트 - 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");

언 골프 :

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

펄, 801 733 문자

나는 이것이 매우 간단한 구현이라고 생각합니다. 기본적으로 각 손에 대해 양복과 얼굴을 개별적으로 정렬합니다. 그런 다음 에이스 카운트가 적은 얼굴의 사본을 다시 만들어 에이스가 적은 직선을 확인할 수 있습니다. 그런 다음 플러시 또는 스트레이트가 있는지, 그리고 높은 카드가 무엇인지 확인합니다. 그런 다음 점수 순서대로 일치를 확인합니다 (먼저 플러시, 4 가지 종류 등). 실제 점수는 손의 유형을 연결 한 다음 중요한 순서대로 카드의 액면 값을 따릅니다 (골프 버전의 _s (), 골프 버전의 u ()). 여기있어:

@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하지만, 나는 직선이 3 가지 종류를 능가한다고 생각합니다
r3mainer
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.