3

Having this issue of my fullHouse function = true when there's a three-of-a-kind. The function checks for a 3 of a kind and a pair but it satisfies the logic with just a three of a kind (D, Ace)(C, Ace)(S, Ace)(D, Ten)(D, 9). This isn't a full house but it's allowing the same 3 aces to satisfy both the pair AND the 3 of a kind.

How do I restrict this so it cannot reduce the 3 of a kind into a pair?


Thanks!

EDIT: F# Newbie

EDIT_2: A full house is when out of your hand of 5 cards you have a 3 of a kind (3 of the same value (suit doesn't matter but they have to be 3x aces or 3x tens etc)) AND a pair (2x ten's, 2x 8's etc - suit doesn't matter)

Input:

fullHouse [(D, K);(C, K);(S, K);(D, T);(D, V 9)];;

Expected output: False, Actual output: True

Input:

fullHouse [(D, K);(C, K);(S, K);(D, T);(C, T)];;

Expected output: True, Actual Output: True

  • Assume that we don't know the rules of poker. What's a _full house_? Also, please provide some input values and their expected outputs. – Mark Seemann Dec 09 '16 at 12:35
  • BTW, slightly related: http://codereview.stackexchange.com/a/143803/3878 – Mark Seemann Dec 09 '16 at 12:35
  • Looking at the edit history, I wonder why you defined a separate case for `T` rather than just use `V 10`. Any reason? – phoog Dec 12 '16 at 17:32

1 Answers1

8

My take on this would be to handle all the cases of Four of a Kind, Full House, Triple, Pair or none of the above all together.

To do this, I would use List.groupBy in order to group by card values. This will give you a list of lists of each group of the same card value. For example:

[(D, K);(C, K);(S, K);(D, T);(D, V 9)] |> List.groupBy (snd);;

Gives the result:

[(K, [(D, K); (C, K); (S, K)]); (T, [(D, T)]); (V 9, [(D, V 9)])]

i.e. A list of three Kings, a list of one Ten and a list of one Nine.

Now you just need to make sure the longest sublists appear at the start for convenient pattern matching, so simply order this list by the number of cards contained in each sublist and then you can pattern match against the hand to obtain the result.

let (|FourOfKind|FullHouse|Triple|Pair|Other|) hand =
    let groups = hand |> List.groupBy (snd) |> List.sortByDescending (List.length << snd)
    match groups with
    |(v, [c1; c2; c3; c4]) :: rest -> FourOfKind (c1, c2, c3, c4)
    |(v, [c1; c2; c3]) :: (v2, [c4; c5]) :: rest -> FullHouse(c1, c2, c3, c4, c5)
    |(v, [c1; c2; c3]) :: rest -> Triple(c1, c2, c3)
    |(v, [c1; c2]) :: rest -> Pair(c1, c2)
    |_ -> Other

You could then do, e.g.

let printHand = function
    |FourOfKind _ -> printfn "Four of a Kind"
    |FullHouse _ -> printfn "Full House"
    |Triple _ -> printfn "Triple"
    |Pair _ -> printfn "Pair"
    |Other -> printfn "Other"

Then in fsi:

printHand [(D, K);(C, K);(S, K);(D, T);(D, V 9)];;
Triple

printHand [(D, K);(C, K);(S, K);(D, T);(C, T)];;
Full House
TheInnerLight
  • 12,034
  • 1
  • 29
  • 52