library(tidyverse)Day 8
Advent of Code: Worked Solutions
Setup
Import libraries:
Read input from file:
input <- read_lines("../input/day08.txt")Convert text input to a character matrix:
mtx <- input |>
str_split("") |>
unlist() |>
matrix(nrow = length(input), byrow = TRUE)Part 1
Define a helper function to check if a coordinate x is within the bounds of the map (mtx):
in_bounds <- \(x, map) between(x[1], 1, nrow(map)) & between(x[2], 1, ncol(map))Define a helper function to compute the antinodes of a given pair of antenna coordinates on a map:
antinode_pair <- function(x1, x2, map) {
diff <- x2 - x1
keep(list(x1 - diff, x2 + diff), ~ in_bounds(.x, map))
}Define a helper function to get the coordinates of every antenna of a given frequency on a map:
get_antennas <- function(freq, map) {
antennas <- which(map == freq, arr.ind = TRUE)
split(antennas, row(antennas))
}Define a function to compute all antinodes of a given frequency in a map:
get_all_antinodes <- function(freq, map, f) {
antennas <- get_antennas(freq, map)
pairs <- combn(antennas, 2)
pairs <- split(pairs, col(pairs))
pairs |>
map(~ f(.x[[1]], .x[[2]], map)) |>
list_flatten() |>
unique()
}Compute the distinct set of frequencies in the map:
freqs <- mtx |>
as.vector() |>
unique() |>
keep(~ .x %in% c(letters, LETTERS, as.character(0:9)))Count all distinct antinode locations across all frequencies in the map:
freqs |>
map(~ get_all_antinodes(.x, mtx, antinode_pair)) |>
list_flatten() |>
unique() |>
length()Part 2
Update the antinode function which computes the antidotes of a given pair of antennas:
antinode_set <- function(x1, x2, map) {
diff <- x2 - x1
antinodes <- list(x1, x2)
i <- 1
while(in_bounds(x2 + i * diff, map)) {
antinodes <- c(antinodes, list(as.integer(x2 + i * diff)))
i <- i + 1
}
i <- 1
while(in_bounds(x1 - i * diff, map)) {
antinodes <- c(antinodes, list(as.integer(x1 - i * diff)))
i <- i + 1
}
antinodes
}Re-run puzzle input:
freqs |>
map(~ get_all_antinodes(.x, mtx, antinode_set)) |>
list_flatten() |>
unique() |>
length()