library(mistlecode)
options(scipen = 999)
df <-
read.csv("input.csv") |>
dplyr::mutate(dplyr::across(
tidyselect::matches('child[2-4]C'),
\(x) ifelse(as.character(x) == " ", NA, x)
))
df$child2C[as.character(df$child2C) == " "] <- NA
df$child3C[as.character(df$child3C) == " "] <- NA
df$child4C[as.character(df$child4C) == " "] <- NA
07: Handy Haversacks
Part 1
level <- c("shiny gold")
oldRows <- 0
while(oldRows != nrow(shinygoldDF)) {
oldRows <- nrow(shinygoldDF)
level <- unlist(shinygoldDF$parent)
shinygoldDF <-
df[as.character(df$parent) %in% level |
as.character(df$child1C) %in% level |
as.character(df$child2C) %in% level |
as.character(df$child3C) %in% level |
as.character(df$child4C) %in% level, ]
}
nrow(shinygoldDF) - 1
[1] 164
Part 2
Holy crap. I actually did it. I had some help from ChatGPT because I really struggle with recursion like this where it can’t just be a for loop (and even with the help it took four years…). I think the key point for me here is that I really like to do early returns, and you can’t. The return must be at the bottom and explicit. I also tried really hard not to use a for
loop, but that makes it a lot harder and more confusing to iterate through everything. I’m hoping I can learn from this and apply it to future recursion problems.
df <-
'input.txt' |>
readLines() |>
stringr::str_replace_all(' bags contain ', ',') |>
stringr::str_remove_all('(bags?[\\. ]?)') |>
stringr::str_split(' ?, ?') |>
purrr::map(\(x) {
x <-
x |>
stringr::str_match('([0-9]*) ?([a-z]+ [a-z]+)') |>
tibble::as_tibble() |>
dplyr::select(-1) |>
dplyr::mutate('V2' = as.integer(.data$V2))
x |>
dplyr::filter(!is.na(.data$V2)) |>
tidyr::uncount(weights = .data$V2) |>
dplyr::pull(.data$V3) |>
list() |>
setNames(x$V3[1])
}) |>
unlist(recursive = FALSE)
Warning: The `x` argument of `as_tibble.matrix()` must have unique column names if
`.name_repair` is omitted as of tibble 2.0.0.
ℹ Using compatibility `.name_repair`.