#' Day 21: Dirac Dice
#'
#' [Dirac Dice](https://adventofcode.com/2021/day/21)
#'
#' @name day21
#' @rdname day21
#' @details
#'
#' **Part One**
#'
#' There\'s not much to do as you slowly descend to the bottom of the
#' ocean. The submarine computer [challenges you to a nice
#' game]{title="A STRANGE GAME."} of *Dirac Dice*.
#'
#' This game consists of a single
#' [die](https://en.wikipedia.org/wiki/Dice), two
#' [pawns](https://en.wikipedia.org/wiki/Glossary_of_board_games#piece),
#' and a game board with a circular track containing ten spaces marked `1`
#' through `10` clockwise. Each player\'s *starting space* is chosen
#' randomly (your puzzle input). Player 1 goes first.
#'
#' Players take turns moving. On each player\'s turn, the player rolls the
#' die *three times* and adds up the results. Then, the player moves their
#' pawn that many times *forward* around the track (that is, moving
#' clockwise on spaces in order of increasing value, wrapping back around
#' to `1` after `10`). So, if a player is on space `7` and they roll `2`,
#' `2`, and `1`, they would move forward 5 times, to spaces `8`, `9`, `10`,
#' `1`, and finally stopping on `2`.
#'
#' After each player moves, they increase their *score* by the value of the
#' space their pawn stopped on. Players\' scores start at `0`. So, if the
#' first player starts on space `7` and rolls a total of `5`, they would
#' stop on space `2` and add `2` to their score (for a total score of `2`).
#' The game immediately ends as a win for any player whose score reaches
#' *at least `1000`*.
#'
#' Since the first game is a practice game, the submarine opens a
#' compartment labeled *deterministic dice* and a 100-sided die falls out.
#' This die always rolls `1` first, then `2`, then `3`, and so on up to
#' `100`, after which it starts over at `1` again. Play using this die.
#'
#' For example, given these starting positions:
#'
#' Player 1 starting position: 4
#' Player 2 starting position: 8
#'
#' This is how the game would go:
#'
#' - Player 1 rolls `1`+`2`+`3` and moves to space `10` for a total score
#' of `10`.
#' - Player 2 rolls `4`+`5`+`6` and moves to space `3` for a total score
#' of `3`.
#' - Player 1 rolls `7`+`8`+`9` and moves to space `4` for a total score
#' of `14`.
#' - Player 2 rolls `10`+`11`+`12` and moves to space `6` for a total
#' score of `9`.
#' - Player 1 rolls `13`+`14`+`15` and moves to space `6` for a total
#' score of `20`.
#' - Player 2 rolls `16`+`17`+`18` and moves to space `7` for a total
#' score of `16`.
#' - Player 1 rolls `19`+`20`+`21` and moves to space `6` for a total
#' score of `26`.
#' - Player 2 rolls `22`+`23`+`24` and moves to space `6` for a total
#' score of `22`.
#'
#' \...after many turns\...
#'
#' - Player 2 rolls `82`+`83`+`84` and moves to space `6` for a total
#' score of `742`.
#' - Player 1 rolls `85`+`86`+`87` and moves to space `4` for a total
#' score of `990`.
#' - Player 2 rolls `88`+`89`+`90` and moves to space `3` for a total
#' score of `745`.
#' - Player 1 rolls `91`+`92`+`93` and moves to space `10` for a final
#' score, `1000`.
#'
#' Since player 1 has at least `1000` points, player 1 wins and the game
#' ends. At this point, the losing player had `745` points and the die had
#' been rolled a total of `993` times; `745 * 993 = 739785`.
#'
#' Play a practice game using the deterministic 100-sided die. The moment
#' either player wins, *what do you get if you multiply the score of the
#' losing player by the number of times the die was rolled during the
#' game?*
#'
#' **Part Two**
#'
#' *(Use have to manually add this yourself.)*
#'
#' *(Try using `convert_clipboard_html_to_roxygen_md()`)*
#'
#' @param pos_a Starting position of player A
#' @param pos_b Starting position of player B
#' @return For Part One, `f21a(x)` returns .... For Part Two,
#' `f21b(x)` returns ....
#' @export
#' @examples
#' f21a(4, 8)
#' \dontrun{
#' max(f21b(4, 8))
#' }
f21a <- function(pos_a, pos_b) {
cycle <- function(i, n) (i - 1) %% n + 1
a <- b <- 0
i <- 1
repeat {
roll1 <- cycle(i:(i + 2), 100)
pos_a <- cycle(pos_a + sum(roll1), 10)
a <- a + pos_a
if (a >= 1000) {
n <- i + 2
break
}
roll2 <- cycle((i + 3):(i + 5), 100)
pos_b <- cycle(pos_b + sum(roll2), 10)
b <- b + pos_b
if (b >= 1000) {
n <- i + 5
break
}
i <- i + 6
}
min(a,b) * n
}
#' @rdname day21
#' @export
f21b <- function(pos_a, pos_b) {
cycle <- function(i, n) (i - 1) %% n + 1
sum_roll3 <- rowSums(expand.grid(1:3,1:3,1:3))
w <- table(sum_roll3)
dirac <- function(pos, score,
o_pos, o_score,
player = 1){
n_wins <- c(0,0)
pos <- cycle(pos + 3:9, 10)
score <- score + pos
win <- score >= 21
n_wins[player] <- sum(w * win)
if (any(!win)) {
res <- lapply(which(!win),
function(i){
dirac(o_pos, o_score,
pos[i], score[i],
player = 2 - player + 1)
})
return(n_wins + colSums(c(w[!win]) * do.call("rbind", res)))
}
return(n_wins)
}
dirac(pos_a, 0, pos_b, 0)
}
f21_helper <- function(x) {
}
#' @param example Which example data to use (by position or name). Defaults to
#' 1.
#' @rdname day21
#' @export
example_data_21 <- function(example = 1) {
l <- list(
a = c(
)
)
l[[example]]
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.