library(tidyverse)
Day 20
Advent of Code: Worked Solutions
Setup
Import libraries:
Read input from file, converting “#”/“.” characters to 1/0 integers:
<- read_lines("../input/day20.txt", skip_empty_rows = TRUE) |>
input str_split("") |>
map(~ case_match(.x, "." ~ 0, "#" ~ 1))
Separate the input into the algorithm sequence and image matrix:
<- pluck(input, 1)
alg <- tail(input, -1) |> do.call(what = rbind) img
Part 1
Print the starting image:
<- \(img) {
print_img image(
t(img)[, nrow(img):1],
col = c("black", "white"),
asp = nrow(img) / ncol(img),
axes = FALSE
)
}
print_img(img)
Define a function to enhance the given image. Since the character representing the infinte expansion in all directions can change from enhancement to enhancement, we track its current value in the inf
argument.
<- function(mtx, inf = 0) {
enhance
# Expand the borders of the image so that all 3x3 subsets are accessible
<- rbind(inf, inf, cbind(inf, inf, mtx, inf, inf), inf, inf)
mtx
# Generate the full set of output coords
<- expand_grid(
mtx_out row = 1:(nrow(mtx) - 2),
col = 1:(ncol(mtx) - 2)
|>
)
# Convert output coords to 3x3 ranges of the input and get the output value
mutate(
bin = map2_chr(row, col, ~ str_flatten(t(mtx[.x + 0:2, .y + 0:2]), "")),
idx = strtoi(bin, base = 2) + 1,
out = alg[idx]
|>
)
# Compress back down into matrix format
pull(out) |>
matrix(nrow = nrow(mtx) - 2, byrow = TRUE)
# Determine the new value of the infinite grid
<- alg[strtoi(str_flatten(rep(inf, 9), ""), base = 2) + 1]
inf_out
lst(mtx = mtx_out, inf = inf_out)
}
Define a function that enhances the image a given number of times:
<- function(img, n) {
enhance_n lst(mtx = img, inf = 0) |>
reduce(1:n, .f = ~ do.call(what = enhance, args = .x), .init = _) |>
pluck("mtx")
}
Enhance the image twice, then count how many pixels are lit in the result:
<- enhance_n(img, n = 2)
result
sum(result)
print_img(result)
Part 2
Enhance the image 50 times:
<- enhance_n(img, n = 50)
result
sum(result)
print_img(result)