C G O
C G O

Reputation: 51

Coin Flip Streaks Challenge - Al Sweigart's Automate The Boring Stuff with python

Looking around the internet for the expected result to this challenge I have found different answers so that I'm not sure what is correct. I think my code looks ok and results in 1.5% but differs from others. So I am looking for the correct answer to this.

Here's the challenge:

Coin Flip Streaks

For this exercise, we’ll try doing an experiment. If you flip a coin 100 times and write down an “H” for each heads and “T” for each tails, you’ll create a list that looks like “T T T T H H H H T T.” If you ask a human to make up 100 random coin flips, you’ll probably end up with alternating head-tail results like “H T H T H H T H T T,” which looks random (to humans), but isn’t mathematically random. A human will almost never write down a streak of six heads or six tails in a row, even though it is highly likely to happen in truly random coin flips. Humans are predictably bad at being random. Write a program to find out how often a streak of six heads or a streak of six tails comes up in a randomly generated list of heads and tails. Your program breaks up the experiment into two parts: the first part generates a list of randomly selected 'heads' and 'tails' values, and the second part checks if there is a streak in it. Put all of this code in a loop that repeats the experiment 10,000 times so we can find out what percentage of the coin flips contains a streak of six heads or tails in a row. As a hint, the function call random.randint(0, 1) will return a 0 value 50% of the time and a 1 value the other 50% of the time. You can start with the following template:

import random
numberOfStreaks = 0
for experimentNumber in range(10000):
    # Code that creates a list of 100 'heads' or 'tails' values.
    # Code that checks if there is a streak of 6 heads or tails in a row.
print('Chance of streak: %s%%' % (numberOfStreaks / 100))

Upvotes: 2

Views: 1213

Answers (1)

mhawke
mhawke

Reputation: 87134

Here is what I believe to be a correct implementation of a solution to the problem. The problem is a little vague, but taken at face value and backed up by the logic that the template code calculates the final percentage by simply dividing by 100, it's straightforward. The divide by 100 is due to the fact that ((n/10000)*100) is the same as (n/100).

import random

n_experiments = 10000
n_streaks = 0
six_heads = 'H' * 6
six_tails = 'T' * 6

for experiment in range(n_experiments):
    run = ''.join(random.choices('HT', k=100))
    if six_heads in run or six_tails in run:
        n_streaks += 1

print(f'Total runs with at least one streak: {n_streaks}')
print(f'Chance of streak: {(n_streaks / n_experiments * 100):.2f}%')

This code generates a string of length 100 containing randomly generated characters H or T. It is easy to search a string for a run of characters simply by using the in operator e.g. 'HHHHHH' in 'THTHHHHHHTTTTHTH' is True.

This code consistently reports the chance to be slightly more than 80% that a run of 6 heads or tails will be present in each 100 flips.

If you change k to 6 such that each experiment has only 6 flips then the result is approx 3%, which is consistent with the calculated probability of 3.125% = (1 * 0.5**5) * 100.

Upvotes: 2

Related Questions