Play Cards

Posted by JH

Play Cards

Google Interview Backtracking

Card game rule: the hand is drawn from a pack of cards (no jokers).
Play cards ONLY when they are

    3 of a kind (...AAA... ) or 4 of a kind(...AAAA...).

    a straight flush of 3 or more cards(...JQK... or ...A23456…... in the same suit).

    Find out whether the player will be able to play the whole hand drawn.

Solution

For every card, we will try to play it by the rules given. If the way of playing does not work, backtrack to the previous state and try another way. For example,

Given hand
[Diamond A, Club A, Heart A, Spade A, Diamond 2, Diamond 3]

Backtracking I. The backtracking goes from trying to play every combination that starts with the first card - Diamond A. a. try Diamond A, Club A, Heart A Mark the 3 cards played. Call recursion on the remaining hand [Spade A, Diamond 2, Diamond 3]. Recursion Level 1 Try to find all the combinations to play that starts with with Spade A. None is found. Try to find all the combinations to play that starts with Diamond 2. None is found. Try to find all the combinations to play that starts with Diamond 3. None is found. End loop. This hand cannot be cleared. Backtrack to previous level b. try Diamond A, Heart A, Spade A Mark the 3 cards played. Call recursion on the remaining hand [Club A, Diamond 2, Diamond 3]. Recursion Level 1 Try to find all the combinations to play that starts with with Club A. None is found. Try to find all the combinations to play that starts with Diamond 2. None is found. Try to find all the combinations to play that starts with Diamond 3. None is found. End loop. This hand cannot be cleared. Backtrack to previous level c. try Diamond A, Club A, Spade A Mark the 3 cards played. Call recursion on the remaining hand [Heart A, Diamond 2, Diamond 3]. Recursion Level 1 Try to find all the combinations to play that starts with with Heart A. None is found. Try to find all the combinations to play that starts with Diamond 2. None is found. Try to find all the combinations to play that starts with Diamond 3. None is found. End loop. This hand cannot be cleared. Return to previous level d. try try Diamond A, Club A, Heart A, Spade A Mark the 4 cards played. Call recursion on the remaining hand [Diamond 2, Diamond 3]. Less than 3 cards cannot clear. Return to previous level. e. try Diamond A, Diamond 2, Diamond 3, Recursion Level 1 Mark the 3 cards played. Call recursion on the remaining hand [Heart A, Spade A, Club A]. Recursion Level 1 Try to find all the combinations to play that starts with with Heart A. Heart A, Spade A, Club A 3 of a kind works. Hand clear. Return true;

Return true on [Diamond A, Club A, Spade A] + [Heart A, Spade A, Club A].

Above is a simple example of backtracking of just 2 levels (level 0 and level 1). The more straight flushes and N of a kind there is in the hand, the more levels of recursion it needs.

Edge cases

A special case to look at is the card Ace. Ace can be in a straight of A, 2, 3..., or Q, K, A.
But there is no such thing like ...K, A, 2 ....

General cases

At every given card, we will try to find All combinations that starts with it. For example for Spade A, try for
3 types of 3 of a kind
[Spade A, Hearth A, Diamond A]
[Spade A, Club A, Diamond A]
[Spade A, Hearth A, Club A]

4 of a kind
[Spade A, Hearth A, Diamond A, Club A]

all the straight flushes with a length greater than 2
[Spade A, Spade 2, Spade 3]
[Spade A, Spade 2, Spade 3, Spade 4]
[Spade A, Spade 2, Spade 3, Spade 4, Spade 5]
[Spade A, Spade 2, Spade 3, Spade 4, Spade 5, Spade 6]
[Spade A, Spade 2, Spade 3, Spade 4, Spade 5, Spade 6, Spade 7]
... all the way till Spade K if there is no missing rank in the middle
If a rank in middle is missing, stop searching for longer straights.

Implementation

//input a 4X13 matrix with 4 suits and 13 ranks of cards. set cards[suit][rank] to 1 if this card in hand.
public static boolean handClear(int[][] cards, int hand) {
    if(hand == 0) return true;
    for(int rank = 12; rank >= 0; rank--) {
        for(int suit = 0; suit < 4; suit++) {
            if(cards[suit][rank] == 1) { //if cards[suit][rank] in hand
                cards[suit][rank] = 0; hand--;
                int smallerRank = rank == 0 ? 12: rank - 1; // look for straight flush that end with this card
                // watch for Ace as a special case that ***QKA and A23*** both valid
                if(cards[suit][smallerRank] == 1) {
                    cards[suit][smallerRank] = 0; hand--;
                    int r = smallerRank - 1;
                    for(; r >= 0 && cards[suit][r] == 1; r--) {   //try playing the straight flush found
                        cards[suit][r] = 0; hand--;
                        if(handClear(cards, hand)) return true;
                    }
                    r++;
                    for(; r <= smallerRank; r++) {  //backtrack if play did not work
                        cards[suit][r] = 1; hand++;
                    }
                }
                //look for 3/4 of a kind for cards[suit][rand]
                int n = cards[0][rank] + cards[1][rank] + cards[2][rank] + cards[3][rank];
                if(n == 3 || n == 2) {
                    int tmp1 = cards[(suit + 1) % 4][rank],
                        tmp2 = cards[(suit + 2) % 4][rank],
                        tmp3 = cards[(suit + 3) % 4][rank];
                    cards[(suit + 1) % 4][rank] = 0; //try playing the 3/4 of a kind
                    cards[(suit + 2) % 4][rank] = 0;
                    cards[(suit + 3) % 4][rank] = 0;
                    hand -= n;
                    if(handClear(cards, hand)) return true;
                    cards[(suit + 1) % 4][rank] = tmp1;   //backtrack if play did not work
                    cards[(suit + 2) % 4][rank] = tmp2;
                    cards[(suit + 3) % 4][rank] = tmp3;
                    hand += n;
                }
                cards[suit][rank] = 1; hand++;
            }
        }
    }
    return false;
}


Get one-to-one training from Google Facebook engineers

Top-notch Professionals

Learn from Facebook and Google senior engineers interviewed 100+ candidates.
Most recent interview questions and system design topics gathered from aonecode alumnus.
One-to-one online classes. Get feedbacks from real interviewers.

Customized Private Class

Already a coding expert? - Advance straight to hard interview topics of your interest.
New to the ground? - Develop basic coding skills with your own designated mentor.
Days before interview? - Focus on most important problems in target company question bank.