← Previous Contents    Next →  

Programming with event and sample spaces (C++)

We solve the problems from the previous section in C++. The main work is the creation of sample spaces, since std seems not as generous as the python libraries in that respect.

First for the dice rolls. The type-definition is

typedef int Dice;
typedef std::vector Roll;
typedef std::vector DiceEvent;

So the outcome of one dice roll is an int. A roll of several dice is a vector of ints, and an event is a vector of vector of ints. The sample space is an example of an event, so that should have type DiceEvent.

Probability of at least one six

DiceEvent sample = createDiceSample(2);
DiceEvent event = filter([](Roll roll) {
      return roll[0] == 6 || roll[1] == 6;
}, sample);

// printing the result
std::cout << event.size() << "/" << sample.size();

Probability of no sixes

event = filter([](Roll roll) {
      return roll[0] != 6 && roll[1] != 6;
}, sample);

Probability of sum is 6 when we roll 2 dice

event = filter([](Roll roll) {
      return roll[0] + roll[1] == 6;
}, sample);

Probability of sum 10 when we roll 3 dice

sample = createDiceSample(3);
event = filter([](Roll roll) {
      return roll[0] + roll[1] + roll[2] == 10;
}, sample);

Probability of sum 13 when we roll 4 dice

sample = createDiceSample(4);
event = filter([](Roll roll) {
      return roll[0] + roll[1] + roll[2] + roll[3] == 13;
}, sample);

Probability of having four sixes when you roll eight dice

sample = createDiceSample(8);
event = filter([](Roll roll) {
      int c = 0;
      for (auto dval : roll) if (dval == 6) c++;
      return c == 4;
}, sample);


Next are the card probabilities. The type definitions are

typedef int Val;
typedef int Suit;
typedef std::pair Card;
typedef std::vector Hand;
typedef std::vector CardEvent;

Both the value and the suit of a card is an int, and a card consists of a pair of a value and a suit. The relevant property std:pair for these examples is the following usage:

Card card;
Val val;
Suit suit;

val = card.first;
suit = card.second;

which pulls out information about the first and second part of the pair. We create our sample space as follows

CardEvent sample = createCardSample();

We also define two functions to help us solve some of the problems.

int countVal(Hand hand, Val val) {
      int c = 0;
      for (Card card : hand) {
            if (card.first == val) c++;
      }
      return c;
}

int countSuit(Hand hand, Suit suit) {
      int c = 0;
      for (Card card : hand) {
            if (card.second == suit) c++;
      }
      return c;
}

Probability of drawing four aces

CardEvent event = filter([](Hand hand) {
      return countVal(hand, 0) == 4;
}, sample);

Probability of drawing two aces and three jacks

event = filter([](Hand hand) {
      return countVal(hand, 0) == 2
          && countVal(hand, 10) == 3;
}, sample);

Probability of all having the same suit

event = filter([](Hand hand) {
      return countSuit(hand, 0) == 5 ||
             countSuit(hand, 1) == 5 ||
             countSuit(hand, 2) == 5 ||
             countSuit(hand, 3) == 5 ||
             countSuit(hand, 4) == 5;
}, sample);

Probability of a pair

event = filter([](Hand hand) {
      return countVal(hand, hand[0].first) +
             countVal(hand, hand[1].first) +
             countVal(hand, hand[2].first) +
             countVal(hand, hand[3].first) +
             countVal(hand, hand[4].first) == 7;
}, sample);


Finally, the queuing examples. Our type definitions are

typedef int Person;
typedef Roll Queue;
typedef DiceEvent QueueEvent;

C++ does have functions for creating permutations. But instead of using those, we take this oppurtunity to practise using filter. So we filter the result from diceSample to create a sample space for queues.

// outside main
bool validQueue(Queue queue)
{
      for (Person p : queue) {
            int c = 0;
            for (Person q : queue) {
                  if (p == q) c++;
            }
           if (c != 1) return false;
     }
     return true;
}

// inside main
QueueEvent sample = createQueueSample(6);
sample = filter(validQueue, sample);

As in the Python examples, the sample space has two interpretations, both of which are useful.

Probability that 0 is at the front

QueueEvent event = filter([](Queue queue) {
      return queue[0] == 0;
}, sample);

Probability that 0 is not at the back

event = filter([](Queue queue) {
      return queue[0] != 5;
}, sample);

Probability that 0 is ahead of 1

event = filter([](Queue queue) {
      return queue[0] < queue[1];
}, sample);

Probability that 0 and 1 occupy the first two positions

event = filter([](Queue queue) {
      return queue[0] < 2 && queue[1] < 2;
}, sample);

Probability that 0 and 1 are ahead of 2 and 3

event = filter([](Queue queue) {
      return queue[0] < queue[2] &&
             queue[0] < queue[3] &&
             queue[1] < queue[2] &&
             queue[1] < queue[3];
}, sample);


← Previous Contents    Next →