2024 Western States 100 Lottery

Author

Peter Ehmann

Published

September 11, 2025

Introduction

{ What is the lottery? }

Lottery Website

Github Repository

Lottery Entrants

Code
# number of people with the respective number of tickets
# this will change year-to-year

one            <- 4122
two            <- 2461
four           <- 1472
eight          <- 870
sixteen        <- 441
thirtytwo      <- 319
sixtyfour      <- 202
onetwentyeight <- 84
twofiftysix    <- 21
fivetwelve     <- 1

# create unique IDs for each individual

tix001 <- (1:one)
tix002 <- (1:two)            + max(tix001)
tix004 <- (1:four)           + max(tix002)
tix008 <- (1:eight)          + max(tix004)
tix016 <- (1:sixteen)        + max(tix008)
tix032 <- (1:thirtytwo)      + max(tix016)
tix064 <- (1:sixtyfour)      + max(tix032)
tix128 <- (1:onetwentyeight) + max(tix064)
tix256 <- (1:twofiftysix)    + max(tix128)
tix512 <- (1:fivetwelve)     + max(tix256)

# create the lottery tickets (entrants can have >1 ticket)

tickets <- c(rep(tix001,1),
             rep(tix002,2),
             rep(tix004,4),
             rep(tix008,8),
             rep(tix016,16),
             rep(tix032,32),
             rep(tix064,64),
             rep(tix128,128),
             rep(tix256,256),
             rep(tix512,512))

{ Insert table here }

Number of entrants: 9993

Number of tickets: 68724

Simulation Results

Code
# initialize the simulation
# these counters for the number of simulations in which a person with that number of tickets is selected

counter001 = 0
counter002 = 0
counter004 = 0
counter008 = 0
counter016 = 0
counter032 = 0
counter064 = 0
counter128 = 0
counter256 = 0
counter512 = 0

# number of simulations

n_sim = 1000

# simulation for loop

for (i in 1:n_sim) {
  winners   <- c()
  while(length(winners)<271) {
    selection <- sample(tickets, size = 1, replace = F)
    winners   <- unique(c(winners,selection))
  }
  if (sum(tix001[1] %in% winners)>0) {
    counter001 = counter001 + 1
  }
  if (sum(tix002[1] %in% winners)>0) {
    counter002 = counter002 + 1
  }
  if (sum(tix004[1] %in% winners)>0) {
    counter004 = counter004 + 1
  }
  if (sum(tix008[1] %in% winners)>0) {
    counter008 = counter008 + 1
  }
  if (sum(tix016[1] %in% winners)>0) {
    counter016 = counter016 + 1
  }
  if (sum(tix032[1] %in% winners)>0) {
    counter032 = counter032 + 1
  }
  if (sum(tix064[1] %in% winners)>0) {
    counter064 = counter064 + 1
  }
  if (sum(tix128[1] %in% winners)>0) {
    counter128 = counter128 + 1
  }
  if (sum(tix256[1] %in% winners)>0) {
    counter256 = counter256 + 1
  }
  if (sum(tix512[1] %in% winners)>0) {
    counter512 = counter512 + 1
  }
}

# output table of results

knitr::kable(
  data.frame(
    `Number of tickets` = c(
      "1 ticket",   "2 tickets",   "4 tickets",   "8 tickets",   "16 tickets",
      "32 tickets", "64 tickets",  "128 tickets", "256 tickets", "512 tickets"),
    `Percent Chance` = c(
      paste0(format(round(counter001*100/n_sim,2),nsmall=2),"%"),
      paste0(format(round(counter002*100/n_sim,2),nsmall=2),"%"),
      paste0(format(round(counter004*100/n_sim,2),nsmall=2),"%"),
      paste0(format(round(counter008*100/n_sim,2),nsmall=2),"%"),
      paste0(format(round(counter016*100/n_sim,2),nsmall=2),"%"),
      paste0(format(round(counter032*100/n_sim,2),nsmall=2),"%"),
      paste0(format(round(counter064*100/n_sim,2),nsmall=2),"%"),
      paste0(format(round(counter128*100/n_sim,2),nsmall=2),"%"),
      paste0(format(round(counter256*100/n_sim,2),nsmall=2),"%"),
      paste0(format(round(counter512*100/n_sim,2),nsmall=2),"%")
    )
  )
)
Number.of.tickets Percent.Chance
1 ticket 0.20%
2 tickets 1.20%
4 tickets 1.30%
8 tickets 2.90%
16 tickets 7.10%
32 tickets 12.60%
64 tickets 26.30%
128 tickets 44.70%
256 tickets 66.20%
512 tickets 88.80%