Enable Javascript in your browser and then refresh this page, for a much enhanced experience.
First solution in Clear category for Probably Dice by colinmcnicholl
import math
def probability(dice_number, sides, target):
"""input: Three arguments. The number of dice, the number of sides per die and the target number as integers.
Output: The probability of getting exactly target number on a single roll of the given dice as a float."""
# upper limit of summation
k_max = math.floor((target - dice_number) / sides)
# multiply summation by constant
prefix = 1 / (sides ** dice_number)
# initialise probablilty
prob = 0
# loop over summation from k == 0 to k == k_max
for k in range(k_max + 1):
try:
start = (-1)**k
middle = (math.factorial(dice_number) / (math.factorial(k) * math.factorial(dice_number - k)))
end = (math.factorial(target - sides * k - 1)) / (math.factorial(dice_number - 1) * math.factorial((target - sides * k - 1) - (dice_number - 1)))
res = start * middle * end
prob += res
except ValueError:
print("factorial not defined for negative values")
return round(prefix * prob, 4)
if __name__ == '__main__':
#These are only used for self-checking and are not necessary for auto-testing
def almost_equal(checked, correct, significant_digits=4):
precision = 0.1 ** significant_digits
return correct - precision < checked < correct + precision
assert(almost_equal(probability(2, 6, 3), 0.0556)), "Basic example"
assert(almost_equal(probability(2, 6, 4), 0.0833)), "More points"
assert(almost_equal(probability(2, 6, 7), 0.1667)), "Maximum for two 6-sided dice"
assert(almost_equal(probability(2, 3, 5), 0.2222)), "Small dice"
assert(almost_equal(probability(2, 3, 7), 0.0000)), "Never!"
assert(almost_equal(probability(3, 6, 7), 0.0694)), "Three dice"
assert(almost_equal(probability(10, 10, 50), 0.0375)), "Many dice, many sides"
Sept. 7, 2017
Comments: