Last active
August 31, 2021 21:07
-
-
Save ha0ye/7cba5e0fc1dde39ef0116b15b05b432f to your computer and use it in GitHub Desktop.
generate random sequences without consecutive repeats
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
f <- function(x) | |
{ | |
n <- sum(x) | |
v <- numeric(n) | |
prev <- NULL | |
for (i in 1:n) | |
{ | |
idx <- x > floor(sum(x)/2) # how many counts are > n/2 | |
if (sum(idx) >= 2) # error if more than 2 (impossible?) | |
{ | |
stop("multiple counts > floor(n/2); x = (", paste(x, collapse = ","), ")") | |
} else if (any(idx)) { | |
j <- which(idx) | |
if (!is.null(prev) && prev == j) # error if one count is > n/2, but was prev | |
{ | |
stop("j == prev; prev = ", prev, ", x = (", paste(x, collapse = ","), ")") | |
} else { # if one count is > n/2, it must be chosen | |
v[i] <- j | |
x[j] <- x[j] - 1 | |
} | |
} else { | |
p <- x # store counts | |
if (!is.null(prev)) { p[prev] <- 0 } # modify counts to not select prev | |
j <- sample(seq_along(x), size = 1, prob = p) # sample, weighted by counts | |
v[i] <- j | |
x[j] <- x[j] - 1 | |
} | |
prev <- j # remember last selection | |
} | |
v | |
} | |
f(c(10, 10)) | |
f(c(4, 4, 5)) | |
f(c(1, 1, 1, 1, 4)) | |
f(c(1, 1, 1, 1, 5)) | |
f(c(1, 1, 1, 1, 6)) # should error out | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment