简体   繁体   中英

Python Programming - Coin Toss

I'm try to write application that will simulate the tossing of a coin a certain number of times to a maximum of 200. It has to record the number of Heads and the number of Tails tossed and display to the user the highest number of Heads tossed in a row, the highest number of Tails tossed in a row and the percentages of heads and tails in addition to that shown.

No negative comments please - just starting to learn python and my attempt is below!

import random as rn

rolls=int(raw_input("Enter the number of rolls: "))

for rolls in range(rolls): 
    print rn.choice(['H', 'HH', 'HHH', 'T', 'TT', 'TTT']),

Generate the tosses using random.choice for each toss:

tosses = ''.join(random.choice('HT') for i in range(rolls))

You can simply count the occurrences of H and T in the resulting string to get the number of heads and tails, respectively:

heads = tosses.count('H')
tails = tosses.count('T')

Finally, you can find the maximum number of heads/tails in a row by splitting the string on the other symbol, and finding the maximum resulting substring:

heads_in_a_row = max(len(s) for s in tosses.split('T'))
tails_in_a_row = max(len(s) for s in tosses.split('H'))

Not incredibly efficient, but it might help you get the idea.

Whenever you need to find consecutive things, it's a good idea to consider itertools.groupby . This approach needs very little extra memory regardless of the number of rolls

from itertools import groupby
import random

rolls = int(raw_input("Enter the number of rolls: "))

tosses = (random.choice('HT') for x in range(rolls))

maxes = {'H': 0, 'T': 0}
sums = {'H': 0, 'T': 0}

for g, v in groupby(tosses):
    n = sum(1 for x in v)
    maxes[g] = max(maxes[g], n)
    sums[g] += n

print maxes['H']
print maxes['T']
print sums['H']*100.0/rolls
print sums['T']*100.0/rolls

It has surprised me that both answers so far have taken a very heavy approach which do a lot of things very inefficiently, especially memory use wise:

  • Constructing and dealing with strings
  • Storing a redundant copy of the input
  • Creating multiple temporary lists and/or strings for the purposes of counting.

Furthermore, neither of these solutions are particularly elegant from a runtime perspective or good at explaining the procedural aspect of what is really going on or needs to be done algorithmically, which is an important aspect of beginner instruction.

The following approach allows you to work with arbitrarily large inputs (amount of rolls), since it does not require keeping any copies. Hence it could easily be converted into a generator function or similar stream processing function. It is also more straightforward and procedurally clean.

import random

rolls=int(raw_input("Enter the number of rolls: "))

desc = {0: "H", 1: "T"}
total = [0, 0]
running = [0, 0]
running_max = [0, 0]
last_rolled = None

for roll in xrange(rolls):
    # we use 0 for heads and 1 for tails
    # this will be the index to the relevant list element for our counters
    rolled = random.randint(0,1)
    total[rolled] += 1

    if last_rolled == rolled:
        # we are continuing the run, flipped the same as last time
        running[rolled] += 1
    else: 
        # there has been a break in the run
        if not last_rolled is None: 
            # as long as this isnt the first iteration
            print running[last_rolled] * desc[last_rolled], 
            running[last_rolled] = 0
        running[rolled] = 1

    # update the max count
    running_max[rolled] = max(running_max[rolled], running[rolled])
    last_rolled = rolled

print running[last_rolled] * desc[last_rolled]
print "total rolls: H=%d, T=%d" % tuple(total)
print "running max: H=%d, T=%d" % tuple(running_max)

Example output:

Enter the number of rolls: 20
HH TTTT HH TT HHHHHHH T H T
total rolls: H=12, T=8
running max: H=7, T=4

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM