Message Boards Message Boards

[✓] 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?

POSTED BY: Mathman12 Jo
Answer
13 days ago

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.

POSTED BY: Neil Singer
Answer
13 days ago

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.

POSTED BY: Tomas Garza
Answer
12 days ago

It works! Thank you very much, you sure saved me some headache! :-)

POSTED BY: Mathman12 Jo
Answer
10 days ago

Group Abstract Group Abstract