Reputation: 151
The following code computes the probability distribution of outcomes of rolling two dice with a variable number of equal sides:
def compute_probability_distribution(sides):
dist = {x+y: 0 for x in range(1, sides+1) for y in range(1, sides+1)}
for die_1 in range(1, sides+1):
for die_2 in range(1, sides+1):
dist[die_1+die_2] = dist[die_1+die_2] + 1
probs = dist.items()
print "Prob dist: ", probs
E.g., for ordinary 6-sided dice the prob dist is [(2,6),(3,2),(4,3),(5,4),(6,5),(7,6),(8,5),)(9,4),(10,3),(11,2),(12,1)], where the first element of each tuple is the sum of the 2 dice, and the second element is the number of ways it can occur on one roll. Can anyone tell me how to sort the above prob dist list by the second element of each tuple so I can output the top (1 or 3) most likely occurrences? I am thinking of using the built-in list sort with some sort of comparison function.
Upvotes: 3
Views: 690
Reputation: 152755
You can do it with a nested comprehensions but you can also compute the most common values by hand if you know the number of sides.
In order of increasing probability:
2
and sides+sides
which only have one "chance". 3
and sides+nsides-1
which have 2. 4
and sides+nsides-2
have 3 sides+1
has the highest probability which is just sides
. If you don't trust me look at the probability distribution for different numbers of sides.
So to get the 3 most common values, you can simply calculate them based on the number of sides:
def compute_probability_distribution(sides):
print([(sides+1, sides), (sides, sides-1), (sides+2, sides-1)])
However, that only works for dices with at least 2 sides. For a single side dice the result will be weird with this function.
Upvotes: 2
Reputation: 477309
I would simply use the data structure that is designed for this: a Counter
:
from collections import Counter
def compute_probability_distribution(sides):
dist = Counter(die_1 + die_2 for die_1 in range(1, sides+1)
for die_2 in range(1, sides+1))
probs = dist.most_common(3)
print "Prob dist: ", probs
For two 6-dices, this then will produce:
>>> compute_probability_distribution(6)
Prob dist: [(7, 6), (6, 5), (8, 5)]
So we obtained six times a sum of seven; five times a sum of six; and five times a sum of eight.
In case you want to make the number of dices arbitrary, you can use:
from collections import Counter
from itertools import product
def compute_probability_distribution(sides,ndices=2,common=3):
dist = Counter(sum(d) for d in product(range(1,sides+1),repeat=ndices))
probs = dist.most_common(common)
print "Prob dist: ", probs
So now we can calculate the 10 most common sums when we roll three 5-dices:
>>> compute_probability_distribution(5,3,10)
Prob dist: [(9, 19), (8, 18), (10, 18), (7, 15), (11, 15), (6, 10), (12, 10), (5, 6), (13, 6), (4, 3)]
Upvotes: 1
Reputation: 109686
probs = [(2,6),(3,2),(4,3),(5,4),(6,5),(7,6),(8,5),(9,4),(10,3),(11,2),(12,1)]
>>> sorted(probs, key=lambda x: x[1]) # x[1] is second element of tuple pair.
[(12, 1),
(3, 2),
(11, 2),
(4, 3),
(10, 3),
(5, 4),
(9, 4),
(6, 5),
(8, 5),
(2, 6),
(7, 6)]
Upvotes: 2