In: Computer Science
In Java
Solve the following problem using arrays:
Past A: Coupon collector is a classic statistic problem with many practical applications. The problem is to pick objects from a set of objects repeatedly and determine how many picks are needed for all the objects to be picked at least once. A variation of the problem is to pick cards from a shuffled deck of 52 cards repeatedly and find out how many picks are needed before you see one of each suit. Assume a picked card is placed back in the deck before picking another. Write a program to simulate the number of picks needed to get total of four cards from each different suit and display the four cards picked (it is possible that a card may be picked twice). Here is a sample run of the program:
Queen of Spades
5 of Clubs
Queen of Hearts
4 of Diamonds
Number of picks: 12
Sample run explanation: As you see in the above run, 12 picks are made to get the four cards from different suits. The other 8 picks (12-4=8) were from the same previously picked suits, so they are not printed. So we continue picking a card until we see at least one card from each of the for suits.
Note: The card pick is with replacement, meaning that when you pick a card from the deck of 52 card, you put it back in the deck. There is chance to see the previously selected card again.
Part B: Put part A in a for loop and repeat it 10,000 times and report the average number of total picks we should have to see 4 cards from different suits.
  PART A Code Below
==========================================================================
public class Card {
    private String suit;
    private String face;
    public Card(String suit, String face) {
        this.suit = suit;
        this.face = face;
    }
    public String getSuit() {
        return suit;
    }
    public String getFace() {
        return face;
    }
    @Override
    public String toString() {
        return getFace() + " of " + getSuit();
    }
}
==========================================================================
import java.util.Random;
public class CouponCollector {
    public static void main(String[] args) {
        String ranks[] = {"2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King", "Ace"};
        String suits[] = {"Spades", "Diamonds", "Clubs", "Hearts"};
        Card deck[] = new Card[ranks.length * suits.length];
        int index = 0;
        for (String rank : ranks) {
            for (String suit : suits) {
                deck[index++] = new Card(suit, rank);
            }
        }
        Random random = new Random();
        int randomCard = 0;
        boolean allSuitPicked[] = {false, false, false, false};
        int attempts = 0;
        while (!allSuitPicked[0] || !allSuitPicked[1] || !allSuitPicked[2] || !allSuitPicked[3]) {
            attempts += 1;
            randomCard = random.nextInt(deck.length);
            Card card = deck[randomCard];
            System.out.println(card);
            if (card.getSuit().equals("Spades")) allSuitPicked[0] = true;
            else if (card.getSuit().equals("Diamonds")) allSuitPicked[1] = true;
            else if (card.getSuit().equals("Clubs")) allSuitPicked[2] = true;
            else if (card.getSuit().equals("Hearts")) allSuitPicked[3] = true;
        }
        System.out.println("Number of picks: "+attempts);
    }
}
==========================================================================

For PART B , Card.class will be the same, have updated the CouponCollector.java class only below is the updated class
import java.util.Random;
public class CouponCollector {
    public static void main(String[] args) {
        String ranks[] = {"2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King", "Ace"};
        String suits[] = {"Spades", "Diamonds", "Clubs", "Hearts"};
        Card deck[] = new Card[ranks.length * suits.length];
        int index = 0;
        for (String rank : ranks) {
            for (String suit : suits) {
                deck[index++] = new Card(suit, rank);
            }
        }
        Random random = new Random();
        int totalAttempts = 0;
        for (int experiment = 1; experiment <= 10000; experiment++) {
            int randomCard = 0;
            boolean allSuitPicked[] = {false, false, false, false};
            int attempts=0;
            while (!allSuitPicked[0] || !allSuitPicked[1] || !allSuitPicked[2] || !allSuitPicked[3]) {
                attempts += 1;
                randomCard = random.nextInt(deck.length);
                Card card = deck[randomCard];
                //System.out.println(card);
                if (card.getSuit().equals("Spades")) allSuitPicked[0] = true;
                else if (card.getSuit().equals("Diamonds")) allSuitPicked[1] = true;
                else if (card.getSuit().equals("Clubs")) allSuitPicked[2] = true;
                else if (card.getSuit().equals("Hearts")) allSuitPicked[3] = true;
            }
            System.out.println("Experiment "+experiment+", Attempts count: "+attempts);
            totalAttempts+=attempts;
        }
        System.out.println("Average number of picks: " + totalAttempts/10000.0);
    }
}
