# Name the poker hand

Given five cards, output the name of the poker hand, which will be one of:

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


If in doubt, refer to the rules at http://en.wikipedia.org/wiki/List_of_poker_hands.

## Input

5 cards from either stdin or commandline arguments. A card is a two letter string on the form RS, where R is rank and S is suit. The ranks are 2 - 9 (number cards), T (ten), J (Jack), Q (Queen), K (King), A (Ace). The suits are S, D, H, C for spades, diamonds, hearts and clubs respectively.

### Example of cards

5H - five of hearts


### Example of input => desired output

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


## Rules

Shortest code wins

### Edit

Looking great so far! I can't really verify all the answers, since I don't know these languages very well and don't have compilers/interpreters for all of them, but I suspect that not everyone have thought about that Aces can be both the highest and the lowest cards of a Straight (flush).

• There is a vaguely related oldie on Stack Overflow. Jun 29, 2012 at 17:19
• Are we allowed to capitalize (or not) hand names as we please? Jul 2, 2012 at 9:41
• Mr.Wizard, sure. Jul 2, 2012 at 14:49

Came up with an answer of my own :)

# Python - 312301 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]


Creates a 2x2 list where the indices of the two dimensions are boolean checks for flush and straight. In case of both, we check if it's a royal flush or just a straight flush. For not flush and not straight, we check for the other hands: m and n holds the highest and second highest amount of same-rank cards; the names of the hands are stored in a list with indices according to m. Sub-checks within this list's values are done with n to seperate one pair from two pair, and three of a kind from house.

Edit: Thanks Nolen Royality for a total of 20 characters saved!

• ... and beat mine. Jul 3, 2012 at 2:06
• Love the new solution, 312 characters is pretty tiny. Very clever method of dealing with one vs two pairs :D Jul 8, 2012 at 19:14
• Thanks :) You're welcome to try it if you want. But you're maybe not using any similar variable as mine m and n. Checking this and watching your code again, I just realized I can shave off some more on the original one ^^ Jul 8, 2012 at 19:32
• Couldn't you lose another 8 chars by switching m,n=g([c.count(x)for x in set(r)]) to m,n=g(map(c.count,set(r)))? Jul 10, 2012 at 5:22
• Woah, you are darn right I could :D Don't know why that slipped my mind. Good catch, thanks! Jul 10, 2012 at 16:03

## Ruby 1.9 (427359348338296 292)

EDIT: Fixed to work with low aces.

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]  The basic idea is to build up an array of the quantity of card in each rank, concatenate the digits into a string, and then run regular expressions to see which hand shape fits. We count the number of distinct suits to determine whether to check it against the different flushes (flush, straight flush, royal flush) or to the other shapes (everything else). Takes the cards as separate command-line args, like so: >ruby poker-hand-golf.rb 3H 5D JS 3C 7C one pair  C, 454 characters #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);}  Run from command line with cards as arguments, e.g. ./a.out 8C 3H 8S 8H 3S Expanded version, with comments: #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); }  Edits: 1. Saved 12 chars by combining and reusing loops. 2. Saved 9 chars by inlining string constant. 3. Saved 19 chars by using stringification in macro, nasty.. • Do h>24 and u[2]>1 work as well as h==25 and u[2]==2? And why is the output of High card conditional on h? What is h if the ranks are, say, 7 6 5 4 2? Jul 24, 2020 at 19:39 ## GolfScript (209 208 207 206 200 199 197 196 chars) 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$+](=  I'm exploiting the offered freedom to tweak capitalisation: my Straight Flush and Royal Flush both capitalise Flush in order to reuse the word from the simple flush. Note: some earlier versions were buggy: they only supported full house when the pair was of lower value than the pair royal. They can be corrected by replacing the space separating - 0 with a $.

Demo

• Now that's a golfed program! I've been looking for ways to shorten it, but can't come up with anything. Using .& to find the distinct chars in a string is a very useful trick. Jul 9, 2012 at 12:45
• @w0lf, that's a fairly standard trick. Howard uses it too in his solution. Jul 9, 2012 at 12:50

## Mathematica, 365

Here is my take on David Carraher's answer.

Shown with white space for some readability.

If[
a = Characters;
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"]
]
] &


One line version:

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

• Nice. You even found space to save in the pattern matching. E.g. _ instead of {_,_,_,_} Jul 2, 2012 at 11:29
• Nice solutions, both of you. For the sake of character count, I think the "Pair" should be named "One Pair", even though it sounds a bit bad, since that is what I posted and others have implemented. Jul 2, 2012 at 21:05
• @Daniero Thanks. I'll fix the name. Jul 3, 2012 at 1:44

# 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: Added 1 char for Ace-low straights ### Python 334, 326 322 Characters 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]]  I know that last one liner is getting pretty unreadable, I'll put up a non-golfed version when I'm happy with with my solution. ### GolfScript, 258 250 characters 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])\;


The program expects input on STDIN as given above and outputs to STDOUT. You may test the code yourself.

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

> 8C 7H 6S TH 9S
Straight

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


Edit: Incorporated w0lf's suggestions.

• Nice solution! You can save 3 chars by putting " of a kind" in a variable, because it's used twice. Jul 7, 2012 at 19:49
• it also works with "Straight" Jul 7, 2012 at 19:54
• @w0lf Thank you. I added your suggestions to the code. Jul 7, 2012 at 20:19
• I think there's a subtle bug with the detection of Straights: AH KH 2C 3H 4H is considered a Straight, but should be High card. Jul 9, 2012 at 20:04
• @w0lf Hmmm, I have to think about that one... Jul 10, 2012 at 5:23

# Mathematica - 500494 465 chars

This solution is based on a poker demonstration by Ed Pegg, Jr. In this version, the cards are treated internally as numbers in Range[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"]]]]


Sample inputs, outputs:

Notes:

f: flush

c: cards (without suit)

s: straight

t: {cards, suites}

d:

• Nice, but how do you get two pair out of JH 4C 2C JD TH? Jun 29, 2012 at 17:28
• You are correct. There is an error that arose when I joined some components together into a pure function. I'll track it down. Jun 29, 2012 at 18:23
• @Daniero The issue you raised has been addressed. Jun 30, 2012 at 18:37
• David, there is a lot of room to compress this. May I? Jul 1, 2012 at 12:06
• @Mr.Wizard Be my guest. I'll watch and learn. Jul 1, 2012 at 13:55