Nommez la main de poker

22

Nommez la main de poker

Étant donné cinq cartes, sortez le nom de la main de poker, qui sera l'une des suivantes:

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

En cas de doute, reportez-vous aux règles sur http://en.wikipedia.org/wiki/List_of_poker_hands .

Contribution

5 cartes à partir d'arguments stdin ou de ligne de commande. Une carte est une chaîne de deux lettres sur le formulaire RS, où R est le rang et S est la couleur. Les rangs sont 2- 9(cartes numérotées), T(dix), J(Jack), Q(Reine), K(Roi), A(As). Les costumes sont S, D, H, Cpour bêches, des diamants, des coeurs et des clubs respectivement.

Exemple de cartes

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

Exemple d'entrée => sortie souhaitée

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

Règles

Victoires de code les plus courtes

modifier

En regardant bien jusqu'à présent! Je ne peux pas vraiment vérifier toutes les réponses, car je ne connais pas très bien ces langues et je n'ai pas de compilateurs / interprètes pour toutes, mais je soupçonne que tout le monde n'a pas pensé que les as peuvent être à la fois les plus élevées et les cartes les plus basses d'un Straight (flush) .

daniero
la source
2
Il y a un ancien vaguement lié sur Stack Overflow .
dmckee
Sommes-nous autorisés à mettre en majuscule (ou non) les noms des mains à notre guise?
Mr.Wizard
Mr.Wizard, bien sûr.
daniero

Réponses:

3

GolfScript ( 209 208 207 206 200 199 199 197 196 caractères)

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

J'exploite la liberté offerte de modifier la capitalisation: mon Straight Flush et Royal Flush capitalisent tous les deux Flush afin de réutiliser le mot du simple flush.

Remarque: certaines versions antérieures étaient boguées: elles ne prenaient en charge full house que lorsque la paire était de valeur inférieure à la paire royal. Ils peuvent être corrigés en remplaçant l'espace séparant - 0par un $.

Démo

Peter Taylor
la source
Voilà un programme golfique! J'ai cherché des moyens de le raccourcir, mais je ne trouve rien. Utiliser .&pour trouver les caractères distincts dans une chaîne est une astuce très utile.
Cristian Lupascu
@ w0lf, c'est une astuce assez standard. Howard l'utilise aussi dans sa solution.
Peter Taylor
8

Entré avec une réponse de ma part :)

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]

Crée une liste 2x2 où les indices des deux dimensions sont des vérifications booléennes pour flush et straight. Dans les deux cas, nous vérifions s'il s'agit d'une quinte flush royale ou simplement d'une quinte flush. Pour ne pas flush et pas directement, nous vérifions les autres mains: met ndétient le plus haut et le deuxième plus grand nombre de cartes de même rang; les noms des aiguilles sont stockés dans une liste d'index selon m. Les sous-vérifications dans les valeurs de cette liste sont effectuées avec npour séparer une paire de deux paires et trois d'une sorte de maison.

Edit: Merci Nolen Royality pour un total de 20 personnages enregistrés!

daniero
la source
1
... et battre le mien.
Mr.Wizard
J'adore la nouvelle solution, 312 caractères est assez petit. Méthode très intelligente pour gérer une ou deux paires: D
Nolen Royalty
Merci :) Vous pouvez l'essayer si vous le souhaitez. Mais vous n'utilisez peut-être pas de variable similaire à la mienne et à la mienne. En vérifiant cela et en regardant à nouveau votre code, je viens de réaliser que je peux en raser un peu plus sur l'original ^^
daniero
1
Ne pourriez-vous pas perdre encore 8 caractères en passant m,n=g([c.count(x)for x in set(r)])à m,n=g(map(c.count,set(r)))?
Nolen Royalty
Woah, vous avez vraiment raison, je pourrais: D Je ne sais pas pourquoi cela m'a glissé. Bonne prise, merci!
daniero
5

Rubis 1.9 (427 359 348 338 296 292)

EDIT : fixe pour fonctionner avec des as faibles.

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]

L'idée de base est de créer un tableau de la quantité de cartes dans chaque rang, de concaténer les chiffres en une chaîne, puis d'exécuter des expressions régulières pour voir quelle forme de main convient. Nous comptons le nombre de combinaisons distinctes pour déterminer s'il faut le comparer aux différentes couleurs (couleur, couleur droite, couleur royale) ou aux autres formes (tout le reste).

Prend les cartes comme des arguments de ligne de commande séparés, comme ceci:

>ruby poker-hand-golf.rb 3H 5D JS 3C 7C
one pair
Paul Prestidge
la source
4

C, 454 caractères

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

Exécuter à partir de la ligne de commande avec des cartes comme arguments, par exemple ./a.out 8C 3H 8S 8H 3S

Version étendue, avec commentaires:

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

Modifications:

  1. 12 caractères enregistrés en combinant et en réutilisant des boucles.
  2. 9 caractères enregistrés en insérant une constante de chaîne.
  3. 19 caractères enregistrés en utilisant la stringification en macro, méchant ..
bébé-lapin
la source
3

Mathematica , 365

Voici mon point de vue sur la réponse de David Carraher.

Montré avec un espace blanc pour une certaine lisibilité.

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

Version une ligne:

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"]]]&
Mr.Wizard
la source
Agréable. Vous avez même trouvé de l'espace pour enregistrer dans la correspondance de motifs. Par exemple _au lieu de{_,_,_,_}
DavidC
De belles solutions, vous deux. Pour le compte des personnages, je pense que la "paire" devrait être nommée "une paire", même si cela semble un peu mauvais, car c'est ce que j'ai publié et que d'autres ont mis en œuvre.
daniero
@Daniero Merci. Je vais fixer le nom.
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"

edit: Ajout de 1 char pour les lignes droites as-low

tmartin
la source
3

Python 334 , 326 322 caractères

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

Je sais que le dernier paquebot devient assez illisible, je mettrai une version non-golfée quand je serai satisfait de ma solution.

Nolen Royalty
la source
2

GolfScript, 258 250 caractères

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

Le programme attend une entrée sur STDIN comme indiqué ci-dessus et des sorties sur STDOUT. Vous pouvez tester le code vous-même .

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

> 8C 7H 6S TH 9S
Straight

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

Edit: incorporé les suggestions de w0lf.

Howard
la source
Bonne solution! Vous pouvez enregistrer 3 caractères en insérant " of a kind"une variable, car elle est utilisée deux fois.
Cristian Lupascu
cela fonctionne aussi avec"Straight"
Cristian Lupascu
@ w0lf Merci. J'ai ajouté vos suggestions au code.
Howard
Je pense qu'il y a un bug subtil avec la détection des droits: AH KH 2C 3H 4Hest considéré comme un droit, mais devrait être une carte haute.
Cristian Lupascu
@ w0lf Hmmm, je dois penser à celui-là ...
Howard
2

Mathematica - 500 494 465 caractères

Cette solution est basée sur une démonstration de poker par Ed Pegg, Jr. Dans cette version, les cartes sont traitées en interne comme des nombres dansRange[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"]]]]

Exemples d'entrées, de sorties:

Les données

Remarques:

f: rincer

c: cartes (sans couleur)

s: droit

t: {cartes, suites}

ré:

DavidC
la source
Bien, mais comment en retirer deux paires JH 4C 2C JD TH?
daniero
Vous avez raison. Une erreur est survenue lorsque j'ai joint certains composants ensemble en une fonction pure. Je vais le retrouver.
DavidC
@Daniero Le problème que vous avez soulevé a été résolu.
DavidC
David, il y a beaucoup de place pour comprimer cela. Puis-je?
Mr.Wizard
@ Mr.Wizard Soyez mon invité. Je vais regarder et apprendre.
DavidC