Nombra la mano de póker

22

Nombra la mano de póker

Dadas cinco cartas, muestra el nombre de la mano de póker, que será una de:

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

En caso de duda, consulte las reglas en http://en.wikipedia.org/wiki/List_of_poker_hands .

Entrada

5 cartas de stdin o argumentos de línea de comandos. Una tarjeta es una cadena de dos letras en el formulario RS, donde R es rango y S es palo. Los rangos son 2: 9(tarjetas de números), T(diez), J(Jack), Q(Reina), K(Rey), A(As). Los trajes son S, D, H, Cde picas, diamantes, corazones y clubes respectivamente.

Ejemplo de cartas

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

Ejemplo de entrada => salida deseada

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

Reglas

El código más corto gana

Editar

¡Luce genial hasta ahora! Realmente no puedo verificar todas las respuestas, ya que no conozco muy bien estos idiomas y no tengo compiladores / intérpretes para todos ellos, pero sospecho que no todos han pensado que los Ases pueden ser tanto los mejores como los mejores. Las cartas más bajas de un Straight (color) .

daniero
fuente
2
Hay un oldie vagamente relacionado en Stack Overflow .
dmckee
¿Se nos permite capitalizar (o no) los nombres de las manos como queramos?
Mr.Wizard
Sr. mago, claro.
daniero

Respuestas:

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$+](=

Estoy explotando la libertad ofrecida para ajustar la capitalización: mi Straight Flush y Royal Flush capitalizan Flush para reutilizar la palabra del simple flush.

Nota: algunas versiones anteriores tenían errores: solo admitían full house cuando el par era de menor valor que el par real. Se pueden corregir reemplazando el espacio que separa - 0con a $.

Manifestación

Peter Taylor
fuente
Ahora que es un programa de golf! He estado buscando formas de acortarlo, pero no puedo encontrar nada. Usar .&para encontrar los caracteres distintos en una cadena es un truco muy útil.
Cristian Lupascu
@ w0lf, ese es un truco bastante estándar. Howard también lo usa en su solución.
Peter Taylor
8

Se me ocurrió una respuesta propia :)

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]

Crea una lista de 2x2 donde los índices de las dos dimensiones son controles booleanos para el vaciado y la recta. En el caso de ambos, verificamos si es una escalera real o simplemente una escalera de color. Para no enjuagar y no derecho, verificamos las otras manos: my ntiene la mayor y la segunda cantidad más alta de cartas del mismo rango; los nombres de las manos se almacenan en una lista con índices según m. Las verificaciones secundarias dentro de los valores de esta lista se realizan npara separar un par de dos pares y tres de un tipo de la casa.

Editar: ¡Gracias a Nolen Royality por un total de 20 personajes guardados!

daniero
fuente
1
... y vencer al mío.
Mr.Wizard
Me encanta la nueva solución, 312 caracteres son bastante pequeños. Método muy inteligente para lidiar con uno contra dos pares: D
Nolen Royalty
Gracias :) Puedes probarlo si quieres. Pero quizás no estés usando ninguna variable similar a la mía m y n. Comprobando esto y viendo su código nuevamente, me di cuenta de que puedo afeitarme un poco más en el original ^^
daniero
1
¿No podrías perder otros 8 caracteres cambiando m,n=g([c.count(x)for x in set(r)])a m,n=g(map(c.count,set(r)))?
Nolen Royalty
Woah, tienes razón, podría: D No sé por qué se me pasó por la cabeza. Buena captura, gracias!
daniero
5

Ruby 1.9 (427 359 348 338 296 292)

EDITAR : arreglado para trabajar con ases bajos.

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]

La idea básica es construir una matriz de la cantidad de cartas en cada rango, concatenar los dígitos en una cadena y luego ejecutar expresiones regulares para ver qué forma de mano encaja. Contamos el número de trajes distintos para determinar si se debe comparar con los diferentes colores (color, color recto, color real) o con las otras formas (todo lo demás).

Toma las tarjetas como argumentos de línea de comando separados, así:

>ruby poker-hand-golf.rb 3H 5D JS 3C 7C
one pair
Paul Prestidge
fuente
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);}

Ejecutar desde la línea de comandos con tarjetas como argumentos, por ejemplo ./a.out 8C 3H 8S 8H 3S

Versión ampliada, con comentarios:

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

Ediciones:

  1. Ahorró 12 caracteres combinando y reutilizando bucles.
  2. Se guardaron 9 caracteres al alinear la cadena constante.
  3. Guardado 19 caracteres mediante el uso de stringificación en macro, desagradable ...
conejo bebé
fuente
3

Mathematica , 365

Aquí está mi opinión sobre la respuesta de David Carraher.

Se muestra con espacio en blanco para cierta legibilidad.

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"]
  ]
] &

Versión de una línea:

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"]]]&
Señor mago
fuente
Agradable. Incluso encontró espacio para ahorrar en la coincidencia de patrones. Por ejemplo, en _lugar de{_,_,_,_}
DavidC
Buenas soluciones, los dos. En aras del recuento de caracteres, creo que el "Par" debería llamarse "Un par", aunque suene un poco mal, ya que eso es lo que publiqué y otros han implementado.
daniero
@Daniero Gracias. Arreglaré el nombre.
Mr.Wizard
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: Se agregó 1 carácter para rectas Ace-low

tmartin
fuente
3

Python 334 , 326322 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]]

Sé que el último trazador de líneas se está volviendo bastante ilegible, pondré una versión sin golf cuando esté satisfecho con mi solución.

Nolen Royalty
fuente
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])\;

El programa espera entrada en STDIN como se indicó anteriormente y salidas a STDOUT. Puede probar el código usted mismo .

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

> 8C 7H 6S TH 9S
Straight

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

Editar: Incorporado w0lf sugerencias.

Howard
fuente
Buena solución! Puede guardar 3 caracteres poniendo " of a kind"una variable, porque se usa dos veces.
Cristian Lupascu
también funciona con"Straight"
Cristian Lupascu
@ w0lf Gracias. Agregué tus sugerencias al código.
Howard
Creo que hay un error sutil en la detección de Straights: AH KH 2C 3H 4Hse considera un Straight, pero debería ser una carta High.
Cristian Lupascu
@ w0lf Hmmm, tengo que pensar en eso ...
Howard
2

Mathematica - 500 494 465 caracteres

Esta solución se basa en una demostración de póker de Ed Pegg, Jr. En esta versión, las tarjetas se tratan internamente como números enRange[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"]]]]

Muestra de entradas, salidas:

datos

Notas:

f: rubor

c: tarjetas (sin palo)

s: recto

t: {tarjetas, suites}

re:

DavidC
fuente
Bien, pero ¿cómo sacas dos pares JH 4C 2C JD TH?
daniero
Estás en lo correcto. Se produjo un error cuando uní algunos componentes en una función pura. Lo rastrearé.
DavidC
@Daniero Se ha solucionado el problema que planteaste.
DavidC
David, hay mucho espacio para comprimir esto. ¿Puedo?
Mr.Wizard
@ Mr.Wizard Sé mi invitado. Yo miraré y aprenderé.
DavidC