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
typedef std::vector
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
typedef std::vector
typedef std::vector
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);