Forum Discussion
Challenge - Evaluate a Poker hand
**For educational purposes only!**
This challenge is taken from Edabit where it's to be solved in JavaScript.
Working from a standard 52-card deck (No Jokers nor additional wild cards, thus no Five of a Kind), evaluate a Poker hand. There are 2,598,960 possible combinations.
It's very do-able but how efficiently can it be done?
Function follows below. How would you solve this task?
//This function evaluates a hand for a standard game of poker using a 52 card deck.
//For educational purposes only!
EvaluateHandλ =
LAMBDA(dealt_hand,
LET(
//Convert dealt hand to vertical array
cards,TOCOL(dealt_hand),
//Generate symbols for 4 suits.
all_suits, CHAR(SEQUENCE(4, , 167)),
//Obtain suits from dealt hand.
suit, RIGHT(cards),
//Extract the rank from the dealt hand.
extract, TEXTBEFORE(cards, all_suits),
//Swap letter rank for number where needed. Ace valued at 14
//if there's a king present in the hand, otherwise 1.
ranks, SORT(SWITCH(
extract,
"K", 13,
"Q", 12,
"J", 11,
"A", IF(OR(extract = "K"), 14, 1),
--extract)),
//Determine if all cards are from same suit.
same_suit?, COUNTA(UNIQUE(suit)) = 1,
//Determine if ranks are in sequence.
in_sequence?, AND(DROP(ranks, 1) - DROP(ranks, -1) = 1),
//Aggregate extracted rank to identify how many cards are from same rank.
agg, DROP(GROUPBY(extract, extract, COUNTA, , 0), , 1),
//Stack all possible logic starting with Royal Flush to Pair.
logic, VSTACK(same_suit? * in_sequence? * MAX(ranks) = 14,
AND(same_suit?, in_sequence?),
OR(agg = 4),AND(MIN(agg) = 2, MAX(agg) = 3),same_suit?,
in_sequence?,OR(agg = 3),IFNA(MODE(agg) = 2, 0),OR(agg = 2)),
//All possible outcomes except High Card.
outcomes, {"Royal Flush";"Straight Flush";"Four of a Kind";
"Full House";"Flush";"Straight";"Three of a Kind";
"Two Pair";"Pair"},
//Evaluate: error results in High Card evaluation.
return, XLOOKUP(TRUE, logic, outcomes, "High Card"),
IF(COUNTA(dealt_hand)=1,"Deal cards",return)));
2 Replies
- m_tarlerBronze Contributor
i don't improvement on what you did per se but think a slightly more interesting challenge is to COMPARE 2 hands. To do this I reworked the Lambda a bit to output an integer value for what level hand it is and a decimal value for the individual cards in order of precedence. probably a more efficient way but see attached. note I also inserted logic to identify 'invalid hands' as either not enough cards or duplicate cards but I don't check for duplicate cards between the 2 hands.
PS - it just occurred to me that this modified output could be useful if this challenge was to get extended to 7 card stud or texas hold'em or include wild card to check each permutation and find the best option
- Patrick2788Silver Contributor
I think the challenge becomes very hairy once tie breaking elements are introduced. I think you've tackled it as best as it can be done. I went back and fourth on modifying the existing function versus creating a new function to run the tie break based on the evaluation. At some point "scope creep" comes into play and things tend to get convoluted!
The way I see the tie-breaking:
It becomes a question if it's best to develop the function to handle poker variants instead of breaking ties which may not be terribly common? (Maybe a question for poker aficionados).