Solution (source code)

= Solution
{c}

Use <inverse transform sampling> for the categorical draw. Validate a finite nonnegative <probability> vector, allowing only a small rounding tolerance in its total, then compare a single uniform draw with the cumulative probabilities:

``
sim1 <- function(p) {
  if (!is.numeric(p) || length(p) == 0L ||
      any(!is.finite(p)) || any(p < 0) ||
      abs(sum(p) - 1) > 1e-12) {
    stop("p must be a nonempty finite probability vector")
  }
  p <- p / sum(p)
  cumulative <- cumsum(p)
  cumulative[length(p)] <- 1
  u <- runif(1)
  as.integer(which(u < cumulative)[1L])
}
``

The returned value is $j$ when $u$ falls in the interval between the previous cumulative sum and the $j$th one. That interval has length $p_j$, so the output has the required probabilities. Strict comparison skips zero-<probability> categories even if a simulated uniform value equals an interval boundary. Exactly one call to `runif(1)` is made.