# [✓] Make a function to check if a poker hand contains exactly one pair?

GROUPS:
 Hi everyone, I'm having a problem where i'm trying to make a function that returns if a poker hand contains exactly one pair. The first code works for a hand of four, but gives an incorrent return for a hand of 5. pairQ[{x_, x_, y_, y_} /; x != y] := False; (* two pair*) pairQ[{___, x_, x_, x_}] := False; (* three of a kind *) pairQ[{___, x_, x_,}] := True; (* one pair *) pairQ[{___}] := False (* something else...*) hand = {2, 3, 4, 4}; pairQ[hand] This will output true since 4 and 4 is the same. pairQ[{___, x_, x_, ___, y_, ___, y_, ___} /; x != y] := False; (* two pair*) pairQ[{_, x_, x_, x_, _}] := False; (* three of a kind *) pairQ[{___, x_, x_, ___}] := True; (* one pair *) pairQ[{___}] := False (* something else...*) hand = {2, 2, 3, 4, 4}; pairQ[hand] This returns true, why? As I interpreted the number of blankspaces indiciate how many elements that can sit at that position. Eg _ = only one element can take its place. __ = 2 and ___= 3 or more. Can anyone help me with this?
 Neil Singer 3 Votes My recommendation is to make the pattern matching less complicated by relying on the Orderless property of functions:Define a function that will match each of your hand types. To make it easier to understand and debug, I don't return true or false -- I return some text and the cards that match. SetAttributes[f, Orderless] f[x_, x_, y_, w_, z_] := {"one Pair", x, y, w, z} /; x != y != z != w f[x_, x_, y_, y_, z_] := {"two Pair", x, y, z} /; x != y != z f[x_, x_, x_, y_, z_] := {"three of a kind", x, y, z} /; x != y != z f[x_, x_, x_, y_, y_] := {"Full House", x, y, z} /; x != y f[_, _, _, _, _] := {"You have junk -- try bluffing"} Note this function does not take your hand list so you must apply it to a list. Here I test to make sure the list is exactly 5 long and apply f to the list. The Orderless property allows the pattern matcher to reshuffle the list. handType[x_List /; Length[x] == 5] := f @@ x To use it: In[12]:= handType[{1, 2, 3, 4, 3}] Out[12]= {"one Pair", 3, 2, 1, 4} You can easily modify this to give you true or false or take the output and test it.
 Another approach: given a hand of 5 numbers -which in the case of poker are all integers between 1 and 13 (ace being 1 and J, Q, K being 11, 12, 13, respectively )-, say, {x1, x2, x3, x4, x5}, calculate testPair: testPair = Length[Gather[{x1, x2, x3, x4, x5}]] The hand will have one pair if testPair is equal to 4.