Inspired by Hooked's answer, I modified his script to compute the expected number of balls drawn to determine some winner in blackout bingo, in a game of a certain number of cards. The code is modified to run on Python 3, and doesn't require the matlibplot module to run.
For one card, the number of balls is surprisingly large, but this has a simple explanation. Just consider the last ball drawn out of all 75, there is about a 1/3 chance the card has that number on it, so a third of the cards won't get a blackout until all the balls are drawn!
The odds get more complicated when the game has lots of cards in it. Generally, the more cards in the game, the fewer balls are needed. For a reasonable sized game, the number of balls is about 60 out of 75.
from numpy import *
from collections import Counter
from multiprocessing import *
def new_board():
cols = arange(1,76).reshape(5,15)
return array([random.permutation(c)[:5] for c in cols])
def new_game():
for token in random.permutation(arange(1,76)):
yield token
def winning(B):
#if (B.sum(axis=0)==5).any(): return True
#if (B.sum(axis=1)==5).any(): return True
#if trace(B)==5 or trace(B.T)==5: return True
if B.sum()==25: return True ## blackout
return False
def game_length(board, game):
B = zeros((5,5),dtype=bool)
B[2,2] = True
for n,idx in enumerate(game, 1):
B[board==idx] = True
if winning(B): return n
def simulation(trials):
C = Counter()
b = new_board()
for _ in range(trials):
C[game_length(b, new_game())] += 1
return C
if __name__ == '__main__':
repeats = 10**2
trials = 10**3
numBoards = 500
P = Pool()
sol = sum(P.map(simulation,[trials,]*repeats))
P.close()
P.join()
X = array(sorted(filter(None, sol.keys())))
Y = array([sol[x] for x in X])
cumY = cumsum(Y)
probnotwon1board = [(float(repeats*trials - y)/(repeats*trials)) for y in cumY]
probnotwonanyboard = [x**numBoards for x in probnotwon1board]
probsomeboardwon = [1 - x for x in probnotwonanyboard]
print("Number of boards: ", numBoards)
print()
print("Ball Winners Cumulative Prob 1 Board Prob No Prob Some")
print(" Winners Not Won Board Won Board Won")
print()
for i in range(len(X)):
print(" {0:2d} {1:6d} {2:6d} {3:1.6f} {4:1.6f} {5:1.6f} ".format(X[i], Y[i], cumY[i], probnotwon1board[i], probnotwonanyboard[i], probsomeboardwon[i]))
print()
A sample run returns
Number of boards: 500
Ball Winners Cumulative Prob 1 Board Prob No Prob Some
Winners Not Won Board Won Board Won
52 1 1 0.999990 0.995012 0.004988
55 3 4 0.999960 0.980198 0.019802
56 7 11 0.999890 0.946482 0.053518
57 8 19 0.999810 0.909365 0.090635
58 17 36 0.999640 0.835243 0.164757
59 35 71 0.999290 0.701085 0.298915
60 63 134 0.998660 0.511479 0.488521
61 75 209 0.997910 0.351307 0.648693
62 154 363 0.996370 0.162301 0.837699
63 228 591 0.994090 0.051624 0.948376
64 379 970 0.990300 0.007645 0.992355
65 529 1499 0.985010 0.000525 0.999475
66 862 2361 0.976390 0.000006 0.999994
67 1327 3688 0.963120 0.000000 1.000000
68 2103 5791 0.942090 0.000000 1.000000
69 3229 9020 0.909800 0.000000 1.000000
70 4611 13631 0.863690 0.000000 1.000000
71 6927 20558 0.794420 0.000000 1.000000
72 10341 30899 0.691010 0.000000 1.000000
73 15244 46143 0.538570 0.000000 1.000000
74 22017 68160 0.318400 0.000000 1.000000
75 31840 100000 0.000000 0.000000 1.000000
A 1000 boards only drops the halfway point to 59 balls from 60. The expected number is almost certainly going to be between 58 and 63 for any reasonable game.