İki poker eli karşılaştırın


14

Meydan okuma:

İki beş kartlı el verildiğinde, hangisinin kazandığını standart poker eli sıralamasına göre belirleyin .

Giriş:

Stdin'den boşluklarla veya komut satırı argümanları olarak hangisini tercih ederseniz edin, on kart. İlk beş kart Oyuncu 1'in elidir, son beş kart ise Oyuncu 2'nin elidir. Her kart, R formunun ve S'nin uygun olduğu RS formunun iki harfli bir dizesi olacaktır. Dereceler sırasıyla 2-9, T için on ve Jack, Queen, King ve Ace için sırasıyla J, Q, K ve A'dır. Takımlar sırasıyla Kalpler, Elmaslar, Kulüpler ve Maçalar için H, D, C, S'dir. Kazanan oyuncunun sayısını '1' veya '2' vermelisiniz.

Kart Örnekleri:

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

Çıkış Örneklerine Giriş:

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

Açıklama: Oyuncu 1'de bir Çift Beş, Oyuncu 2'de bir Çift Sekiz vardır.

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

Açıklama: Her iki oyuncunun da özel bir şeyi yok, ama Oyuncu 1'in yüksek kartı As, Oyuncu 2'nin yüksek kartı Kraliçe.

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

Açıklama: Oyuncu 1'de Üç As, Oyuncu 2'de Flush of Diamonds var.

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

Açıklama: Her iki oyuncu da bir Çift Kraliçeye sahiptir, ancak Oyuncu 1'in en yüksek ikinci kartı Dokuz iken Oyuncu 2'nin Yedi'dir.

Kurallar ve Açıklamalar:

  • Bakınız poker elleri sıralaması standart ellerini karşılaştıran ayrıntıları için.
  • Her el çiftinde tekrarlanan kart olmadığını varsayabilirsiniz.
  • Her durumda kesin bir kazanan olduğunu varsayabilirsiniz.
  • Takım elbise bir elin sıralamasını etkilemez. Örneğin, farklı takımlardan iki floş royal eşittir (bu nedenle her iki oyuncunun da floş royal olduğu her giriş önceki kural tarafından geçersizdir).
  • Bu kod golf olduğundan, en kısa cevap kazanır.

Notlar:


Özür dilerim özür dilerim! Bu benim ilk kod golf sorum.
komando

Bu son soru olan codegolf.stackexchange.com/q/23743/15599 ve içinde belirtilen 5 kartlı versiyona benzer . Ancak bu sorular sadece elin türünü belirtmek için gereklidir. Burada büyük bir fark, her iki oyuncunun da aynı ele sahip olması durumunda, hangisinin kart sıralamasına göre daha iyi olduğunu belirlememiz gerektiğidir (örneğin, en iyi ilk çift, ikinci çift ve gerekirse tek kart olan iki çift için). bu bir kopya değil. Her zaman benzer soruları arayın, onları bağlayın, (yaptığınızı görüyorum) ve göndermeden önce neden kopya olmadığını savunmaya hazır olun.
Level River St

Flop ve el aynı ise ne olur?
Ismael Miguel

@IsmaelMiguel Bu sürümde flop yoktur. Birbirine karşı değerlendirilmesi gereken iki ayrı el vardır.
komando

1
Daha önce burada
Hasturkun

Yanıtlar:


2

Haskell - 352 339 karakter

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

Koşar:

& 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 ve yorum yaptı, böylece tekniği görebilirsiniz:

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 karakter

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:])))

El tipi için bir karakterle başlayıp, türün belirli varyasyonunu (örneğin, hangi kartta sadece 4'ünüz vardı?) Açıklayan karakterleri izleyen her el için bir dize oluşturmayı seçtim. Beraberlik durumunda kalan kartların değerleri (eğer her iki oyuncunun da aynı çift çifti varsa, 5. kartın kimin kazanacağına karar vermesi gerekir). Oldukça kapsamlı bir şekilde test ettim, ama aslında poker oynamıyorum, umarım doğru anladım. Ayrıca, henüz tam olarak golf oynamadığını biliyorum, muhtemelen birkaç düzine karakterden sonra tıraş olabilirim.


İle 5 karakter öldür _=lambda c:chr(97+c). Ayrıca, :s ve =s'den sonra bazı gereksiz boşluklarınız var . Son olarak, ;girinti için kullanılan boşluğu azaltmak için ifadeleri ayırmak için yeni satırlar yerine kullanın .
user12205

Lambda ile güzel bir, teşekkürler!
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)}

kullanımı:

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

kaynak


1

perl, 801 733 karakter

Bunun oldukça basit bir uygulama olduğuna inanıyorum. Temel olarak, her el için takım elbise ve yüzleri ayrı ayrı sıralarız. Sonra asların düşük saydığı yüzlerin başka bir kopyasını yaparız, böylece düşük aslı düzlükleri kontrol edebiliriz. Daha sonra düz veya düz olup olmadığımızı ve yüksek kartın ne olduğunu belirleriz. Sonra sadece skor sırasına göre maçları kontrol ediyoruz (önce düz yıkamaları, sonra dört çeşit vb. Kontrol ediyoruz). Gerçek puan sadece el türünün birleştirilmesinden sonra kartların yüz değerlerinin önem sırasına göre sıralanmasıdır (golf edilmemiş versiyonda _s (), golf edilmiş versiyonda u ()). İşte burada:

@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

Ve işte daha az golf oynayan eşdeğer:

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 TDbir sonuç üretir 2, ancak bence düz bir tür üçü yener
r3mainer
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.