Reputation: 3
So I just started learning python 4 days ago from C++ and I got bit stuck on one coding challenge and is calculating the probability of throwing five different numbers when you throw five six-sided dice. I did many researches, I tried many ways but still couldn't make it. This is my piece of code:
def numOne(roll):
return len([dice1 for dice1 in roll if dice1 == 1])
def numTwo(roll):
return len([dice2 for dice2 in roll if dice2 == 2])
def numThree(roll):
return len([dice3 for dice3 in roll if dice3 == 3])
def numFour(roll):
return len([dice4 for dice4 in roll if dice4 == 4])
def numFive(roll):
return len([dice5 for dice5 in roll if dice5 == 5])
def numSix(roll):
return len([dice6 for dice6 in roll if dice6 == 6])
r = range(1,7)
sample = [(i,j,k,l,m) for i in r for j in r for k in r for l in r for m in r]
event1 = [roll for roll in sample if numOne(roll) == 1]
event2 = [roll for roll in sample if numTwo(roll) == 1]
event3 = [roll for roll in sample if numThree(roll) == 1]
event4 = [roll for roll in sample if numFour(roll) == 1]
event5 = [roll for roll in sample if numFive(roll) == 1]
event6 = [roll for roll in sample if numSix(roll) == 1]
print (len(event1)*len(event2)*len(event3)*len(event4)*len(event5)*len(event6), "/" ,len(sample))
or this:
def numOne(roll):
return len([dice1 for dice1 in roll if dice1 == 1])
def numTwo(roll):
return len([dice2 for dice2 in roll if dice2 == 2])
def numThree(roll):
return len([dice3 for dice3 in roll if dice3 == 3])
def numFour(roll):
return len([dice4 for dice4 in roll if dice4 == 4])
def numFive(roll):
return len([dice5 for dice5 in roll if dice5 == 5])
def numSix(roll):
return len([dice6 for dice6 in roll if dice6 == 6])
r = range(1,7)
sample = [(i,j,k,l,m) for i in r for j in r for k in r for l in r for m in r]
event = [roll for roll in sample if numOne(roll)==1 and numTwo(roll)==1 and
numThree(roll)==1 and numFour(roll)==1 and numFive(roll)==1 or
numSix(roll)==1]
print(len(event) / len(sample))
Both are wrong, of course. I'm not giving up yet, will edit out if I get to anything, meanwhile any tips or advise is appreciated.
Here is a much simpler example to explain what I'm trying to get to: Calculating the probability of having one six when we roll three dice:
def numsix(roll):
return len([dice for dice in roll if dice == 6])
r = range(1,7)
sample = [(i,j,k,l) for i in r for j in r for k in r for l in r]
event = [roll for roll in sample if numsix(roll)==1]
print(len(event) / len(sample))
Upvotes: 0
Views: 1718
Reputation: 169
If you are trying to simulate the probability, especially with rolling dice, then you should be using a strategy called the Monte Carlo simulation to include randomness.
Your code does not include any sort of randomness. Excluding the fact that both of your code samples calculate an incorrect result, it always calculates the same result. If no random sampling is included, then it implies that you already know in advance what is going to happen and your problem becomes a straight calculation.
Python is a very different animal than C++. You should not try to use your knowledge of an object-oriented language to write code using an interpretive programming language.
import random
same = 0
totalRolls = 100000
for i in range(1, totalRolls + 1):
myRolls = []
while len(myRolls) < 5:
myRolls.append(random.randint(1, 6))
if len(set(myRolls)) == 5:
same += 1
print(same / totalRolls)
The above is an example of a solution that uses a Monte Carlo approach over 100,000 iterations. Each iterations 'rolls' 5 six-sided dice, and adds them to a list. It then converts the list into a set and checks the length. Sets remove duplicates, so the only way to 'roll' five different numbers is for the set to have a length of 5. Otherwise, there was a duplicate.
I would read up on Python's documentation and then attempt to revise your code to make it work similar to the snippet above.
Edit: If you are looking for an average expected value using your code snippet, you can do something like this:
r = range(1,7)
sample = [(i,j,k,l,m) for i in r for j in r for k in r for l in r for m in r]
for i in sample:
if len(set(i)) == 5:
same1 += 1
print(same1 / len(sample))
...or you can use a mathematical approach: on the first roll there are 6 possible favored results. The next roll there will be 5 possible favored results, the roll after that there are 4 and so on and so on. This is 6!
. If you divide this number by the total number of outcomes per total number of rolls e.g. 6*6*6*6*6 = 6^6
you will also get your answer: 0.0925925925...
Upvotes: 2