The draw-position test
One question, answerable from a site's own results page: when a competition is drawn, does the winning ticket land anywhere among the tickets sold with equal chance?
What you need
For each completed competition: the number of tickets sold, the maximum number of tickets, and the winning ticket number (or numbers). Most UK competition sites publish all three on a results or completed-competitions page. Record them as you find them, with the date you looked.
The test
- For each winning ticket, work out its position: the winning number divided by the number of tickets sold. A position of 0.02 means the ticket sat 2% of the way into the tickets sold.
- If the draw is a fair pick over the tickets sold, positions are spread evenly between 0 and 1. About 2% of winners fall below 0.02, about 10% below 0.10, and the median sits near 0.5.
- Count how many winning tickets fall below 0.02 and below 0.10, and compare with what a fair draw would produce. The chance of seeing at least the observed count by luck is a binomial tail probability (code below).
- Group competitions by size (for example under 15,000 tickets sold, 15,000 to 50,000, over 50,000). A defect that only considers an early, fixed-size portion of entries shows up as a bias that grows with competition size, while small competitions look normal.
Checks before you conclude anything
- How are ticket numbers issued? If numbers are handed out in order, position against tickets sold is the right measure. If numbers are scattered across the whole range (you will see winning numbers higher than the sold count on small competitions), measure against the maximum as well. A fair draw passes both.
- Can buyers pick their numbers? Chosen numbers cluster on favourites (1 to 31, round numbers). That can put a few extra winners in the low range on small competitions. It cannot put 40 of 60 winners in the first 2% of a 700,000-ticket competition.
- Sample size. One strange draw means nothing. Twenty do. Report the probability and let it speak.
- Multiple winners. Treat each winning ticket as one observation. For a single competition, the chance that all k winners sit at or below the highest of them is (highest position) to the power k.
What a result does and does not show
A failed test shows that the published winning tickets are not consistent with a random pick over the tickets sold. It does not show why. A draw procedure that reads only the first page of entries from a database, a spreadsheet sorted the wrong way, a numbering scheme the results page doesn't explain, or a choice by someone: all leave the same mark. Only the operator can say which, so every FairDraw audit asks them before it is published and prints their answer.
Reproduce it
Save the results as a CSV with the columns competition, tickets_sold, max_tickets, winning_ticket and run:
import csv
from math import comb
rows = list(csv.DictReader(open("draws.csv")))
def tail(n, k, p): # chance of at least k hits in n tries at probability p
return sum(comb(n, i) * p**i * (1 - p)**(n - i) for i in range(k, n + 1))
for label, lo, hi in [("under 15k", 0, 15000), ("15k to 50k", 15000, 50000), ("50k+", 50000, 10**12)]:
pos = sorted(int(r["winning_ticket"]) / int(r["tickets_sold"])
for r in rows if lo <= int(r["tickets_sold"]) < hi)
if not pos:
continue
n = len(pos); low2 = sum(p < 0.02 for p in pos); low10 = sum(p < 0.10 for p in pos)
print(f"{label}: {n} winners, {low2} in first 2% (expected {0.02*n:.1f}, chance {tail(n, low2, 0.02):.1e}), "
f"{low10} in first 10% (expected {0.10*n:.1f}, chance {tail(n, low10, 0.10):.1e}), median position {pos[n//2]:.3f}")
The CSV for each audit is linked from its page, so the figures can be checked line by line.
Reading the probability
Winning the UK Lotto jackpot is about 1 in 45 million (107.7). Choosing one specific atom from the observable universe is about 1 in 1080. Results in the 10-10 range are not bad luck; results in the 10-50 range are not luck at all.