Skip to content

Instantly share code, notes, and snippets.

@andrequeiroz
Last active October 9, 2018 00:15
Show Gist options
  • Save andrequeiroz/1bc2cbcc6bd4e0a65e17eabf09c6c934 to your computer and use it in GitHub Desktop.
Save andrequeiroz/1bc2cbcc6bd4e0a65e17eabf09c6c934 to your computer and use it in GitHub Desktop.
Custom bingo cards for the lazy
library(ggplot2)
bingo_numbers <- function(n, max_outcome) {
n <- as.integer(n)
if (length(n) > 1 || n <= 0) {
stop("n must be a single integer greater than zero")
}
if (max_outcome < 25 || max_outcome %% 5 != 0) {
stop("maximum outcome must be a multiple of 5 greater than 20")
}
if (choose(max_outcome / 5, 5) ** 4 * choose(max_outcome/ 5, 4) < n) {
stop("n is greater than the number of possibilities")
}
result <- sample((0 * max_outcome / 5 + 1):(1 * max_outcome / 5),
size = 5, replace = FALSE)
for (w in 1:4) {
result <- c(result,
sample((w * max_outcome / 5 + 1):((w + 1) *
max_outcome / 5),
size = ifelse(w == 2, 4, 5), replace = FALSE))
}
result <- as.data.frame(t(result))
if (n > 1) {
i <- 2
while (i <= n) {
candidate <- sample((0 * max_outcome / 5 + 1):(1 * max_outcome / 5),
size = 5, replace = FALSE)
for (w in 1:4) {
candidate <- c(candidate,
sample((w * max_outcome /
5 + 1):((w + 1) * max_outcome / 5),
size = ifelse(w == 2, 4, 5),
replace = FALSE))
}
candidate <- t(candidate)
check <- TRUE
for (j in 1:(i - 1)) {
if (sum(sort(candidate) == sort(result[j, ])) == 24) {
check <- FALSE
}
}
if (check) {
result <- rbind(result, candidate)
i <- i + 1
}
}
}
return(result)
}
bingo_card <- function(numbers, ordered = FALSE) {
numbers <- as.numeric(numbers)
x <- c(1:5, rep(1:5, each = 5))
y <- c(rep(6, 5), rep(5:1, times = 5))
if (ordered) {
numbers <- sort(numbers)
x <- rep(1:5, times = 6)
y <- rep(6:1, each = 5)
}
theme_set(theme_minimal())
theme_update(axis.text = element_blank(), axis.title = element_blank(),
panel.grid = element_blank(), legend.position = "none")
## logo <- png::readPNG("./logo.png")
## logo <- grid::rasterGrob(logo, interpolate = TRUE)
card_coords <- data.frame(x = x, y = y,
shade = c(rep(1, 5), rep(0, 12), 1, rep(0, 12)),
label = c(unlist(strsplit("CESTP", "")),
numbers[1:12], NA, numbers[13:24]))
g <- ggplot(data = card_coords, mapping = aes(x = x, y = y)) +
geom_tile(mapping = aes(fill = factor(shade)), colour = "black") +
geom_rect(xmin = 0.5, xmax = 5.5, ymin = 0.5, ymax = 6.5,
fill = "transparent", colour = "black", size = 1.5) +
geom_rect(xmin = 0.5, xmax = 5.5, ymin = 5.5, ymax = 6.5,
fill = "transparent", colour = "black", size = 1.5) +
geom_text(mapping = aes(x = x, y = y, label = label), size = 12,
data = subset(card_coords, !is.na(label))) +
## annotation_custom(logo, xmin = 2.5, xmax = 3.5,
## ymin = 2.5, ymax = 3.5) +
scale_fill_manual(values = c("transparent", grey(.85))) +
coord_fixed()
return(g)
}
print_cards <- function(n, max_outcome, filename) {
values <- bingo_numbers(n, max_outcome)
card_list <- list()
for (i in 1:n) {
card_list[[i]] <- bingo_card(values[i, ], ordered = FALSE)
}
cards <- gridExtra::marrangeGrob(card_list, ncol = 2, nrow = 2,
top = quote(paste0(g, "/", npages)))
ggsave(filename = filename, plot = cards, width = 210, height = 297,
units = "mm")
}
## test
## bingo_card(bingo_numbers(1, 90))
## generate cards
print_cards(20, 90, "/tmp/cartelas.pdf")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment