08: Haunted Wasteland
file <- 'input.txt'
dir <-
file |>
readLines(n = 1) |>
stringr::str_split_1('')
dt <-
file |>
readr::read_csv(skip = 2, trim_ws = TRUE, col_names = FALSE) |>
tidyr::separate(X1, into = c('start', 'L'), sep = ' = \\(') |>
dplyr::mutate('R' = stringr::str_remove_all(.data$X2, '\\)')) |>
dplyr::select(-'X2')
Rows: 718 Columns: 2
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr (2): X1, X2
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
Part 1
I have evidence that I struggled some other time, but I have no recollection. This was pretty easy, just had an off-by-one to deal with to get around the modulo of length sometimes being zero.
Part 2
I hate when there’s a fancy math way. It’s just least common multiples this time and I’m super dumb for not thinking of this sooner. I did have to be careful with match
instead of %in%
because that would return the indices in the incorrect order and cause everything to fail.
start <- function(end, dir) {
dt[[dir]][match(end, dt$start)]
}
count <- 0
end <-
dt |>
dplyr::filter(grepl('A$', .data$start)) |>
dplyr::pull(.data$start)
targets <-
dt |>
dplyr::filter(grepl('Z$', .data$start)) |>
dplyr::pull(.data$start)
target_pos <- integer(length(end))
repeat {
end <- start(end, dir[(count %% length(dir)) + 1])
if (any(end %in% targets)) {
target_pos[end %in% targets] <- count
if (!any(target_pos == 0)) break
}
count <- count + 1
}
cheapr::scm(target_pos + 1)
[1] 10818234074807