library(tidyverse)
Day 6
Advent of Code: Worked Solutions
Setup
Import libraries:
Read text input from file:
<- read_lines("../input/day06.txt") input
Convert text input of the map into a 1/0 matrix (saving the guard’s initial location):
<- input |>
mtx str_split("") |>
unlist() |>
case_match("." ~ 0, "#" ~ 1, c("^", "v", "<", ">") ~ 2) |>
matrix(nrow = length(input), byrow = TRUE)
<- as.vector(which(mtx == 2, arr.ind = TRUE))
init
<- replace(mtx, mtx == 2, 0) mtx
Part 1
Define a function that loops through guard positions until it leaves the map, returning a list of all positions where they turned:
<- c(1, ncol(mtx), nrow(mtx), 1)
maxdim <- c(-1, 1, 1, -1)
mtxdir <- c(1, 2, 1, 2)
mtxaxis
<- function(mtx, init) {
guard_path <- init
guard <- list(guard)
hist <- 1
idx
repeat {
<- mtxdir[idx]
dir <- maxdim[idx]
dim <- mtxaxis[idx]
axis
if (axis == 1) {
<- mtx[(guard[1] + dir):dim, guard[2]]
path else {
} <- mtx[guard[1], (guard[2] + dir):dim]
path
}
# Quit if we reach the edge of the map without an obstacle
if (all(path == 0)) {
<- dim
guard[axis] <- c(hist, list(guard))
hist return(hist)
}
# Move the guard
<- guard[axis] + dir * head(which(path == 1) - 1, 1)
guard[axis]
# If we've entered a loop (same position + same direction), exit early
if (list(guard) %in% hist) {
# (we can't compare nested lists directly, so must compare str vers)
<- map_chr(hist, ~ str_flatten(.x, collapse = "|"))
hist_str <- str_flatten(guard, collapse = "|")
guard_str if (idx %in% ((which(guard_str == hist_str) - 2) %% 4 + 1))
return()
}
# Update the guard's history and the indexing
<- c(hist, list(guard))
hist <- idx %% 4 + 1
idx
} }
Get the guard’s path for the puzzle input, then count the number of unique positions visited by the guard:
<- guard_path(mtx, init)
path
<- map2(head(path, -1), tail(path, -1), \(source, target) {
path_full expand_grid(row = source[1]:target[1], col = source[2]:target[2])
|>
}) bind_rows() |>
distinct()
nrow(path_full)
Part 2
For each location in the full path (except the starting location), add an obstacle to the matrix. Check the result for loops:
|>
path_full tail(-1) |>
pmap_lgl(\(row, col) {
<- 1
mtx[row, col] is.null(guard_path(mtx, init))
|>
}) sum()