How to resolve the algorithm Dice game probabilities step by step in the Python programming language

Published on 12 May 2024 09:40 PM

How to resolve the algorithm Dice game probabilities step by step in the Python programming language

Table of Contents

Problem Statement

Two players have a set of dice each. The first player has nine dice with four faces each, with numbers one to four. The second player has six normal dice with six faces each, each face has the usual numbers from one to six. They roll their dice and sum the totals of the faces. The player with the highest total wins (it's a draw if the totals are the same). What's the probability of the first player beating the second player? Later the two players use a different set of dice each. Now the first player has five dice with ten faces each, and the second player has six dice with seven faces each. Now what's the probability of the first player beating the second player? This task was adapted from the Project Euler Problem n.205: https://projecteuler.net/problem=205

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Dice game probabilities step by step in the Python programming language

The provided code is a Python program that calculates the probability of winning in a dice game. It defines three different functions to calculate the probability of winning, each with a different approach. The first function, gen_dict, generates a dictionary that counts the number of ways to get each possible sum when rolling multiple dice. It uses the itertools.product function to generate all possible combinations of dice rolls and then increments the count for each sum. The second function, beating_probability, uses the dictionary generated by gen_dict to calculate the probability of one player beating another player in a dice game. It considers all possible combinations of dice rolls for both players and calculates the probability of each player winning. The third function, winning, uses the combos function to generate a list of the number of ways to get each possible sum when rolling multiple dice. It then uses this list to calculate the probability of one player beating another player in a dice game. The code includes examples of how to use each function to calculate the probability of winning in a dice game. The code is well-written and easy to understand. It uses Python's built-in functions and modules effectively to solve the problem. Here is a more detailed explanation of the code: The gen_dict function takes two arguments: n_faces, the number of faces on each die, and n_dice, the number of dice being rolled. It returns a dictionary that counts the number of ways to get each possible sum when rolling the dice. The beating_probability function takes four arguments: n_sides1, the number of sides on the dice for player 1, n_dice1, the number of dice being rolled by player 1, n_sides2, the number of sides on the dice for player 2, and n_dice2, the number of dice being rolled by player 2. It returns the probability of player 1 beating player 2 in the dice game. The winning function takes four arguments: sides1, a list of the numbers on the sides of the dice for player 1, n1, the number of dice being rolled by player 1, sides2, a list of the numbers on the sides of the dice for player 2, and n2, the number of dice being rolled by player 2. It returns the probability of player 1 beating player 2 in the dice game. The code includes examples of how to use each function to calculate the probability of winning in a dice game. The code is well-written and easy to understand. It uses Python's built-in functions and modules effectively to solve the problem.

Source code in the python programming language

from itertools import product

def gen_dict(n_faces, n_dice):
    counts = [0] * ((n_faces + 1) * n_dice)
    for t in product(range(1, n_faces + 1), repeat=n_dice):
        counts[sum(t)] += 1
    return counts, n_faces ** n_dice

def beating_probability(n_sides1, n_dice1, n_sides2, n_dice2):
    c1, p1 = gen_dict(n_sides1, n_dice1)
    c2, p2 = gen_dict(n_sides2, n_dice2)
    p12 = float(p1 * p2)

    return sum(p[1] * q[1] / p12
               for p, q in product(enumerate(c1), enumerate(c2))
               if p[0] > q[0])

print beating_probability(4, 9, 6, 6)
print beating_probability(10, 5, 7, 6)


from __future__ import print_function, division

def combos(sides, n):
    if not n: return [1]
    ret = [0] * (max(sides)*n + 1)
    for i,v in enumerate(combos(sides, n - 1)):
        if not v: continue
        for s in sides: ret[i + s] += v
    return ret

def winning(sides1, n1, sides2, n2):
    p1, p2 = combos(sides1, n1), combos(sides2, n2)
    win,loss,tie = 0,0,0 # 'win' is 1 beating 2
    for i,x1 in enumerate(p1):
        # using accumulated sum on p2 could save some time
        win += x1*sum(p2[:i])
        tie += x1*sum(p2[i:i+1])
        loss+= x1*sum(p2[i+1:])
    s = sum(p1)*sum(p2)
    return win/s, tie/s, loss/s

print(winning(range(1,5), 9, range(1,7), 6))
print(winning(range(1,11), 5, range(1,8), 6)) # this seem hardly fair

# mountains of dice test case
# print(winning((1, 2, 3, 5, 9), 700, (1, 2, 3, 4, 5, 6), 800))


from __future__ import division, print_function
from itertools import accumulate # Python3 only

def combos(sides, n):
    ret = [1] + [0]*(n + 1)*sides # extra length for negative indices
    for p in range(1, n + 1):
        rolling_sum = 0
        for i in range(p*sides, p - 1, -1):
            rolling_sum += ret[i - sides] - ret[i]
            ret[i] = rolling_sum
        ret[p - 1] = 0
    return ret

def winning(d1, n1, d2, n2):
    c1, c2 = combos(d1, n1), combos(d2, n2)
    ac = list(accumulate(c2 + [0]*(len(c1) - len(c2))))

    return sum(v*a for  v,a in zip(c1[1:], ac)) / (ac[-1]*sum(c1))


print(winning(4, 9, 6, 6))
print(winning(5, 10, 6, 7))

#print(winning(6, 700, 8, 540))


  

You may also check:How to resolve the algorithm Case-sensitivity of identifiers step by step in the Julia programming language
You may also check:How to resolve the algorithm Lucas-Lehmer test step by step in the Frink programming language
You may also check:How to resolve the algorithm Tokenize a string step by step in the PARI/GP programming language
You may also check:How to resolve the algorithm CSV data manipulation step by step in the UNIX Shell programming language
You may also check:How to resolve the algorithm Perfect numbers step by step in the PL/I programming language