:

## Using the set data type can simplify logic

Let's take another look at the dice rolling example:

Simulate rolling 8 dice 10 times.

roll := rand(1..6);
for i from 1 to 10 do;
dice := ['roll()' \$8]; # dice contains 8 random values, each from 1..6
end do;

Let's say you want to check the list "dice" to see if all faces are
represented.

One way to do this is to write a proc which creates an array indexed
1..6; and initialize the array to zero; and then check the dice list ...
incrementing the associated array index for each value in the dice list.
Finally ... check the built array to see if all index values are non-zero.

This is in fact what I originally did.

It later occurred to me; that it is much simpler to just built a set
from the dice list ... and then check if that set is {1,2,3,4,5,6}.

Here is an example proc which implements this concept:

check_all_faces := proc(l :: list)
local faces,die;
faces := {};
for die in l do faces := faces union { die } end do;
return (evalb(faces={1,2,3,4,5,6}));
end proc:

This can then be used in the loop which is rolling the dice;
to determine the probability that all faces are displayed.

For example:

roll := rand(1..6);
count := 0;
k := 100000;
for i from 1 to k do;
dice := ['roll()' \$8];
if check_all_faces(dice) then
count := count + 1;
end if;
end do:
printf("count=%d, prob= %d/%d = %f\n",count,count, k, evalf(count/k));

This gives an estimate for the probability of all faces being shown
when 8 dice are rolled. Works out to roughly 11%.

-Jay Pedersen

﻿