Don't like ads? PRO users don't see any ads ;-)

# Untitled

By: a guest on May 21st, 2012  |  syntax: None  |  size: 5.06 KB  |  hits: 13  |  expires: Never
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
1. games = open('bowlarama.txt').read().splitlines() # load bowling data
2.
3. def score(data): # this function calculates the score of the given data
4.     score = 0 # initialize the score to 0
5.     val = {'x': 10, '/': 10, '-': 0, '': 0} # strikes and spares will be
6.                                             # counted as 10, whereas empty
7.                                             # strings (such as when bonus could
8.                                             # go out ouf bounds) and - (which
9.                                             # indicates a third frame 10 roll
10.                                             # that never occurs) count as 0
11.     for i in range(10):                     # then we add the literal values
12.         val[str(i)] = i                     # of 0-9 to the dict
13.     for i in range(len(data) - (data[-3] == 'x' and 2 or 0)):
14.     # this iterator is where a lot of the magic happens; whenever we see a
15.     # strike, we have to add the next two rolls to obtain the bonus; however,
16.     # we don't want to add bonuses for strikes that occur as bonuses in the
17.     # final frame; to that end, we count right up to the end of the data
18.     # string unless the first roll in frame 10 is a strike, in which case
19.     # we only count up to that strike
20.         if data[i] == 'x': # STRIKE!
21.             score += i < len(data) - 1 and 10 or 0 # we add 10 to score unless
22.                                                    # the strike in question is
23.                                                    # part of a frame-10 bonus
24.             bonus = i < len(data) - 2 and data[i+1:i+3] or ''
25.             # bonus contains the data for the next two rolls (as a joined
26.             # string) unless we are handling a frame-10 bonus, in which case
27.             # it is empty, thus adding no additional points to score
28.             if '/' in bonus: # here we have a spare in the bonus! regardless
29.                              # of what the other piece of data is...
30.                 score += 10  # we add 10 to the score
31.             else: # if there is no spare in the bonus...
32.                 for j in bonus:     # we iterate over the bonus and add the
33.                     score += val[j] # numerical value to score; this is not the
34.                                     # same as val[bonus[0]] + val[bonus[1]],
35.                                     # because we must also consider that there
36.                                     # will only be 1 piece of bonus data if the
37.                                     # strike in question is in frame 10
38.         elif data[i] == '/': # SPARE!
39.             score += 10      # we add 10 regardless
40.             score += val[data[i+1:i+2]] # then we obtain the roll that occured
41.                                         # after the spare and add it to the
42.                                         # total; again, taking into account the
43.                                         # various ways that frame 10 can be
44.                                         # tricky, this can't just be
45.                                         # + val[data[i+1]], otherwise it would
46.                                         # go out of bounds if, for instance
47.                                         # the tenth frame is x4/, where the
48.                                         # last bowl is a strike, and then the
49.                                         # player gets to roll two more bonus
50.                                         # balls and ends up sparing. Bless
51.                                         # the Python gods who decided it would
52.                                         # be a good idea to allow range slices
53.                                         # to go out of bounds.
54.         else:   # neither STRIKE nor SPARE
55.             if i < len(data) - 1 and data[i+1] == '/': # check the next roll
56.                 score += 0  # if the user ends up sparing, we don't want to
57.                             # add this value to the score, because we're
58.                             # already adding 10 for every spare we see
59.             else:   # no strike, no spare, and no spare in the next roll
60.                 if i < len(data) - 1:     # as long as this isn't the ver last
61.                     score += val[data[i]] # roll, add its numerical value to the
62.                                           # total; this is where val[] really
63.                                           # shines, because this line accounts
64.                                           # for every possible final roll
65.                                           # x, /, -, or 0-9
66.     return score # cause the function to return the tallied score
67.
68. total = 0.0 # initalized total as float(0) because we want the average
69.             # rounded to the nearest hundredth
70. for g in games: # iterate over each of the sequences of rolls in the game data
71.     total += score(g) # add the result of the scory tally to the total
72.
73. print total / len(games) # calculate the average by dividing the number of
74.                          # games into the accumulated total; we will receive
75.                          # a decimal number (91.462895) that doesn't require
76.                          # rounding, so we're done. Answer: 91.46