Bingo 90 Strip Generator (UK Version)

851 Views Asked by At

The rules of the Bingo UK Game:

  • there are 90 bingo balls.
  • A bingo ticket consists of 9 columns and 3 rows. For each ticket:
    • A row contains exactly five numbers and four blanks.
    • A column consists of one, two or three numbers and never three blanks.
    • The columns are occupied by the number chosen from 1-9 (only nine), 10-19 (ten), 20-29 ... 70-79 and importantly 80-90 (eleven).
    • Numbers in columns are ordered from top to bottom.
  • a strip consists of 6 bingo tickets, such that a strip contains all 90 bingo balls.

I am trying to figure out how to generate random strips based on the probabilities of numbers.

What I tried:

First I replaced all numbers from 1 to 90 with 1 and all spaces with -1, and I tried to calculate the probabilities of me getting a 1, following all the rules of the game. I got that in order to get a 1 in the first column, the first row there is a 5/9 probability for row and a 9/18 probability for column. These probabilities decrease when I get a 1. After I would correctly place the 1s on the bingo board I would replace them with the randomly generated number.

1) Is my strategy of replacing all numbers with 1s and -1s correct, or do I also have to consider the probabilities of for example, getting first a 2 instead of a 3 in the first column?

2) What is the formula for calculating the probabilities for these numbers? I do not know if my solution is correct or how to calculate the probabilities of the numbers.

1

There are 1 best solutions below

11
On

THIS IS INCORRECT

As pointed out by Daniel Mathias, I overlooked the requirement that each row have exactly $4$ blanks. I don't see any practical way of doing this if each pattern of blanks is to have an equal chance of occurrence. The number of possible patterns is very large, I think, and I do't see how to generate a strip so that all strips have equal chance of occurrence.

I don't think you are going about it in the most effective way. I think you should consider generating the entire strip, column by column. For the first column, there are $18$ cells, $9$ of which will be blank, subject to the condition that not all three cells on a single ticket can be blank.

Choose $9$ elements from $18$, without replacement. If numbers $1,2,3$ or $4,5,6$, etc. are all picked reject the sample and try again. When you have a valid distribution of the blanks, generate a random permutation of the numbers from $1$ to $9$, using a random shuffle algorithm. Distribute the numbers into the non-blank cells, in order. Finally, sort the numbers that fall on the same ticket into increasing order.

Then do a similar thing for each of the remaining columns in turn.

I wrote a python script that works along the lines I suggested.

import random

cells = list(range(18))
cols = 9*[None]
cols[0] = list(range(1, 10))
for j in range(1, 8):
    cols[j] = list(range(10*j, 10*(j+1)))
cols[8] = list(range(80,91))

def blanks(k):
    while True:
        sample = random.sample(cells, k)
        for n in range(0,18,3):
            if all(x in sample for x in (n,n+1,n+2)):
                break
        else:  # loop else
            return sorted(sample)

def column(n):
    # generate column n for all tickets
    answer = 18*[-1]
    blank = blanks(18-len(cols[n]))
    for b in blank:
        answer[b] = 0
    random.shuffle(cols[n])
    index = 0
    for n in cols[n]:
        while answer[index] == 0:
            index += 1
        answer[index] = n
        index += 1
    for tkt in range(6):
        col = answer[3*tkt:3*(tkt+1)]
        blank = col.count(0)
        assert blank != 3
        if blank == 0:
            answer[3*tkt:3*(tkt+1)]=sorted(col)
        if blank == 1:
            zero = col.index(0)
            M = max(col)
            m = sum(col) - M
            if zero == 0:
                answer[3*tkt:3*(tkt+1)] = [0,m,M]
            elif zero == 1:
                answer[3*tkt:3*(tkt+1)] = [m,0,M]
            else:
                answer[3*tkt:3*(tkt+1)] = [m,M,0]
    return answer

def strip():
    answer = 6*27*[None]
    for n in range(9):
        col = column(n)
        for row in range(18):
            answer[9*row+n] = col[row]
    return answer

def printStrip(s):
    index = 0
    for ticket in range(6):
        for row in range(3):
            for col in range(9):
                print('%02d '%s[index], end='')
                index += 1
            print()
        print()

printStrip(strip())  

While I'm not proud of this code (my brain seems to have gone on vacation today) it seems to work. Here is typical output.

09 14 22 00 00 51 63 70 81 
00 17 25 33 40 00 65 77 84 
00 00 27 35 00 00 66 78 87 

03 10 00 00 45 53 61 79 00 
00 11 00 36 00 58 64 00 00 
00 00 20 00 00 59 00 00 90 

07 12 21 00 41 00 69 72 80 
00 00 29 38 43 55 00 00 00 
08 00 00 00 47 00 00 75 00 

01 15 00 00 44 00 62 00 82 
00 16 23 00 00 50 00 76 88 
00 00 28 32 49 54 00 00 89 

04 13 00 30 00 00 00 73 00 
06 19 00 34 42 00 67 00 83 
00 00 24 37 48 57 00 00 86 

02 00 26 31 46 52 60 00 85 
00 18 00 39 00 56 68 71 00 
05 00 00 00 00 00 00 74 00      

The double zeroes represent blanks, of course.