Dê um nome à mão de pôquer


22

Dê um nome à mão de pôquer

Dadas cinco cartas, produza o nome da mão de poker, que será uma das seguintes:

High card
One pair
Two pair
Three of a kind
Straight
Flush
Full house
Four of a kind
Straight flush
Royal Flush

Em caso de dúvida, consulte as regras em http://en.wikipedia.org/wiki/List_of_poker_hands .

Entrada

5 cartas dos argumentos stdin ou da linha de comando. Um cartão é uma sequência de duas letras no formulário RS, onde R é a classificação e S é o naipe. As fileiras são 2- 9(cartas numéricas), T(dez), J(Valete), Q(Rainha), K(Rei), A(Ás). Os ternos são S, D, H, Cpara pás, diamantes, corações e clubes, respectivamente.

Exemplo de cartões

5H - five of hearts
TS - ten of spades
AD - ace of diamonds

Exemplo de entrada => saída desejada

3H 5D JS 3C 7C => One pair
JH 4C 2C JD 2H => Two pair
7H 3S 7S 7D 7C => Four of a kind
8C 3H 8S 8H 3S => Full house

Regras

O código mais curto vence

Editar

Parece ótimo até agora! Na verdade, não consigo verificar todas as respostas, pois não conheço muito bem esses idiomas e não tenho compiladores / intérpretes para todos eles, mas suspeito que nem todos tenham pensado que o Ases pode ser o mais alto e o mais importante. as cartas mais baixas de um Straight (flush) .


2
Há um oldie vagamente relacionado no Stack Overflow .
dmckee

Temos permissão para colocar em maiúscula (ou não) nomes de mãos como quisermos?
Mr.Wizard

Mr.Wizard, com certeza.
Daniero 02/07/2012

Respostas:


3

GolfScript ( 209 208 207 206 200 199 197 196 caracteres)

3/zip:^0={10,''*"TJQKA"+?}/]:?15,{?\{=}+,,}%2,-$6,14.),++@$/):|;[!!2*^1=.&,(!+5+]or{/}*'Full house
Two pair
One pair
ThreeKFourKHigh card
Flush
Straight''K'/' of a kind
'*n/~|1$"Royal"if" "+2$+](=

Estou explorando a liberdade oferecida para ajustar a capitalização: meu Straight Flush e Royal Flush usam maiúsculas Flush para reutilizar a palavra do flush simples.

Nota: algumas versões anteriores eram de buggy: elas só suportavam full house quando o par era de menor valor que o par royal. Eles podem ser corrigidos substituindo o espaço que separa - 0por a $.

Demo


Agora esse é um programa de golfe! Estive procurando maneiras de reduzi-lo, mas não consigo pensar em nada. Usar .&para encontrar os caracteres distintos em uma string é um truque muito útil.
Cristian Lupascu

@ w0lf, esse é um truque bastante comum. Howard também o usa em sua solução.
Peter Taylor

8

Veio com uma resposta própria :)

Python - 312 301 298

R,K,F,S,g=' 23456789TJQKA2345A',' of a Kind','Flush','Straight ',sorted
s,r=''.join(g(raw_input(),key=R.find)).split()
n,m=g(map(r.count,set(r)))[-2:]
print[[F,[0,'High Card','TOwnoe'[n&1::2]+' Pair',['Full House','Three'+K][n&1],'Four'+K][m]],[[S,'Royal '][r[0]=='T']+F,S]][r in R][len(set(s))>1]

Cria uma lista 2x2 em que os índices das duas dimensões são verificações booleanas de flush e straight. No caso de ambos, verificamos se é um royal flush ou apenas um straight flush. Para não ficar nivelado e não reto, verificamos as outras mãos: men detemos a maior e a segunda maior quantidade de cartas do mesmo valor; os nomes das mãos são armazenados em uma lista com índices de acordo com m. As verificações secundárias dentro dos valores desta lista são feitas npara separar um par de dois pares e três do mesmo tipo da casa.

Edit: Obrigado Nolen Royality por um total de 20 caracteres salvos!


1
... e venceu o meu.
Mr.Wizard

Adoro a nova solução, 312 caracteres é muito pequeno. Método muito inteligente de lidar com um vs dois pares: D
Nolen Royalty

Obrigado :) Você pode experimentá-lo, se quiser. Mas talvez você não esteja usando nenhuma variável semelhante à m me n. Marcar esta e vendo o seu código novamente, eu só percebi que eu posso raspar um pouco mais sobre o original ^^
daniero

1
Você não poderia perder outros 8 caracteres alternando m,n=g([c.count(x)for x in set(r)])para m,n=g(map(c.count,set(r)))?
Nolen Royalty

Woah, você está certo que eu poderia: D Não sei por que isso me passou pela cabeça. Boa captura, obrigado!
Daniero 10/07/12

5

Ruby 1.9 (427 359 348 338 296 292)

EDIT : corrigido para trabalhar com ases baixos.

o,p=%w(flush straight)
f=/1{5}|1{4}0+1$/
s=[0]*13
puts Hash[*$*.map{|c|s['23456789TJQKA'.index c[0]]+=1;c[1]}.uniq[1]?[f,p,?4,'four'+a=' of a kind',/3.*2|2.*3/,'full house',?3,'three'+a,/2.*2/,'two pair',?2,'one pair',0,'high card']:[/1{5}$/,'royal '+o,f,p+' '+o,0,o]].find{|r,y|s.join[r]}[1]

A idéia básica é criar uma matriz da quantidade de cartões em cada classificação, concatenar os dígitos em uma sequência e executar expressões regulares para ver qual o formato da mão. Contamos o número de naipes distintos para determinar se ele deve ser verificado nos diferentes flushes (flush, straight flush, royal flush) ou nas outras formas (tudo o resto).

Aceita os cartões como argumentos de linha de comando separados, da seguinte maneira:

>ruby poker-hand-golf.rb 3H 5D JS 3C 7C
one pair

4

C, 454 caracteres

#define L for(a=1;a<6;a++)for(b=0;b<13;b++)
#define U u[b+6]
#define R(x,y) if(x)puts(#y);else
b,f,r,h=0,s=0,u[20]={0};main(int a,char**v){L U+=v[a][0]=="23456789TJQKA"[b];f=v[1][1];L{if(v[a][1]!=f)f=0;u[a]+=a==U;if(b>7)h+=U;if(a*13+b<64||!U)r=0;else if(++r==5)s=1;}R(f&&h==25,Royal flush)R(f&&s,Straight flush)R(u[4],Four of a kind)R(u[3]&&u[2],Full house)R(f,Flush)R(s,Straight)R(u[3],Three of a kind)R(u[2]==2,Two pair)R(u[2],One pair)R(h,High card);}

Executar a partir da linha de comando com cartões como argumentos, por exemplo ./a.out 8C 3H 8S 8H 3S

Versão expandida, com comentários:

#define L for(a=1;a<6;a++)for(b=0;b<13;b++)
#define R(x,y) if(x)puts(#y);else
#define U u[b+6]
b,f,r,h=0,s=0,u[20]={0};
main(int a,char**v){
    // card usage - u[6..]
    L U+=v[a][0]=="23456789TJQKA"[b];
    // NOTE: lets expand the inner body of the loop in the answer so this looks more sane:
    // flush
    f=v[1][1];L if(v[a][1]!=f)f=0;
    // count of usages - u[0..5] 
    L u[a]+=a==U;
    // high cards x5
    L if(b>7)h+=U;
    // straights
    L if(a*13+b<64||!U)r=0;else if(++r==5)s=1;        
    // display
    R(f&&h==25,Royal flush)
    R(f&&s,Straight flush)
    R(u[4],Four of a kind)
    R(u[3]&&u[2],Full house)
    R(f,Flush)
    R(s,Straight)
    R(u[3],Three of a kind)
    R(u[2]==2,Two pair)
    R(u[2],One pair)
    R(h,High card);    
}

Edições:

  1. Economizou 12 caracteres combinando e reutilizando loops.
  2. Salva 9 caracteres, alinhando a constante da string.
  3. Salva 19 caracteres usando a stringification em macro, desagradável.

3

Mathematica , 365

Aqui está minha opinião sobre a resposta de David Carraher.

Mostrado com espaço em branco para facilitar a leitura.

If[
  a = Characters;
  x = Thread;
  r = Range;
  d = Sort[a@StringSplit@# /. x[a@"23456789TJQKA" -> 2~r~14]];
  {t, u} = Sort[Last /@ Tally@#] & /@ x@d;
  c = First /@ d;
  f = u == {5};
  S = "Straight";
  c == r[b = d[[1, 1]], b + 4],
  If[f,
   If[c == 10~r~14, "Royal Flush", S <> " flush"], S],
  If[f, "Flush",
   Switch[t,
    {_, 4},    "Four of a kind",
    {2, 3},    "Full house",
    {__, 3},   "Three of a kind",
    {_, 2, 2}, "Two pair",
    {__, 2},   "One pair",
    _,         "High card"]
  ]
] &

Versão de uma linha:

If[a=Characters;x=Thread;r=Range;d=Sort[a@StringSplit@#/.x[a@"23456789TJQKA"->2~r~14]];{t,u}=Sort[Last/@Tally@#]&/@x@d;c=First/@d;f=u=={5};S="Straight";c==r[b=d[[1,1]],b+4],If[f,If[c==10~r~14,"Royal Flush",S<>" flush"],S],If[f,"Flush",Switch[t,{_,4},"Four of a kind",{2,3},"Full house",{__,3},"Three of a kind",{_,2,2},"Two pair",{__,2},"One pair",_,"High card"]]]&

Agradável. Você até encontrou espaço para economizar na correspondência de padrões. Por exemplo, em _vez de{_,_,_,_}
DavidC

Soluções agradáveis ​​para vocês dois. Por uma questão de contagem de caracteres, acho que o "Pair" deve ser nomeado "One Pair", mesmo que pareça um pouco ruim, já que foi isso que eu postei e outros implementaram.
Daniero 02/07/2012

@ Daniero Obrigado. Eu vou consertar o nome.
precisa saber é o seguinte

3

K, 294 295

d:{F:"Flush";S:"Straight ";P:" Pair";K:" of a kind";$[(f:1=#?,/-1#'c)&("AJKQT")~a@<a:,/j:1#'c:" "\:x;"Royal ",F;f&s:(4#1)~1_-':a@<a:,/(("A23456789TJQKA")!1+!14)@j;S,F;4=p:|/#:'=j;"Four",K;(2;3)~u:a@<a:,/#:'=j;"Full House";f;F;s;S;3=p;"Three",K;(1;2;2)~u;"Two",P;(1;1;1;2)~u;"One",P;"High Card"]}

.

k)d'("TS JS QS KS AS";"3S 4S 5S 7S 6S";"JC JH KS JD JS";"JC JH 2S JD 2C";"2C 9C TC QC 6C";"8C 5D 9H 6C 7D";"8C 8D 9H 8S 7D";"8C 8D 9H 2S 9D";"8C 8D 4H 2S 9D";"3C 8D 4H 2S 9D")
"Royal Flush"
"Straight Flush"
"Four of a kind"
"Full House"
"Flush"
"Straight "
"Three of a kind"
"Two Pair"
"One Pair"
"High Card"

editar: Adicionado 1 caractere para retas Ás-baixas


3

Python 334 , 326 322 caracteres

p,f,l,t,o=" pair"," of a kind"," Flush","Straight","A23456789TJQK"
v,u=zip(*raw_input().split())
s=''.join(sorted(v,key=o.find))
print{5:"High card",7:"One"+p,9:"Two"+p,11:"Three"+f,13:"Full house",17:"Four"+f,23:t,24:l[1:],25:t,42:t+l,44:"Royal"+l}[(sum(map(v.count,v)),24)[len(set(u))<2]+((0,20)[s=="ATJQK"],18)[s in o]]

Sei que o último liner está ficando bastante ilegível, vou colocar uma versão sem golfe quando estiver satisfeito com minha solução.


2

GolfScript, 258 250 caracteres

3/zip~;.&,(!\{"23456789TJQKA"?}%$.(\{.@- 8%}%\;"\1"-!\.1/.&{1$\-,}%1.$?)"Four"" of a kind":k+{.,2="Full house"{.2\?)"Three"k+{.3-,({.3\?)"One pair"{;"Straight":?;2$2$&{(8="Royal"?if" flush"+}{;?{"Flush""High card"if}if}if}if}"Two pair"if}if}if}if])\;

O programa espera entrada no STDIN, conforme indicado acima, e sai para STDOUT. Você pode testar o código você mesmo .

> 8C 3H 8S 8H 3S
Full house

> 8C 7H 6S TH 9S
Straight

> AH 3H 4S 2H 6S
High card

Editar: Incorporado sugestões w0lf.


Ótima solução! Você pode salvar 3 caracteres inserindo " of a kind"uma variável, porque é usada duas vezes.
Cristian Lupascu 07/07/2012

ele também trabalha com"Straight"
Cristian Lupascu

@ w0lf Obrigado. Eu adicionei suas sugestões ao código.
217 Howard

Eu acho que há um bug sutil na detecção de Straights: AH KH 2C 3H 4Hé considerado um Straight, mas deve ser um cartão High.
Cristian Lupascu

@ w0lf Hmmm, eu tenho que pensar sobre isso ...
Howard

2

Mathematica - 500 494 465 caracteres

Esta solução é baseada em uma demonstração de poker de Ed Pegg, Jr. Nesta versão, os cartões são tratados internamente como números emRange[2,14]

v[x_] := Block[{d, t, c, f, s},
 d = Sort@ToExpression[Characters[ImportString[x, "Table"][[1]]] /. {"T" -> 10, "J" -> 11, "Q" -> 12, "K" -> 13, "A" -> 14}];t = Sort /@ Map[Length, Split /@ Sort /@ Transpose@d, {2}];c = d[[All, 1]];f = (t[[2]] == {5});s = c == Range[b = d[[1, 1]], b + 4];
If[s,
 If[f, If[c == 10~Range~14, "royal flush", "straight flush"],"straight"],
 If[ f, "flush",
Switch[t[[1]],
 {1, 4}, "four of a kind",
 {2, 3}, "full house",
 {1, 1, 3}, "three of a kind",
 {1, 2, 2}, "two pair",
 {1, 1, 1, 2}, "one pair",
 {1, 1, 1, 1, 1}, "high card"]]]]

Entradas e saídas de amostra:

dados

Notas:

f: nivelado

c: cartas (sem naipe)

s: reto

t: {cartões, suítes}

d:


Legal, mas como você consegue dois pares JH 4C 2C JD TH?
Daniero

Você está certo. Ocorreu um erro quando juntei alguns componentes em uma função pura. Vou rastrear.
29412

@ Daniero O problema que você levantou foi resolvido.
DavidC

David, há muito espaço para comprimir isso. Posso?
precisa saber é o seguinte

@ Mr.Wizard Seja meu convidado. Eu vou assistir e aprender.
DavidC
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.