# Libraries
library(tidyverse)
# Read input from file
<- read_lines("../input/day08.txt", skip_empty_rows = TRUE) input
Day 8
Advent of Code: Worked Solutions
Setup
Part 1
Define antinode functions:
# Check if a coordinate is in the bounds of the map
<- function(x, map) {
in_bounds between(x[1], 1, nrow(map)) & between(x[2], 1, ncol(map))
}
# Compute the antinodes of a given pair of antennas
<- function(x1, x2, map) {
antinode_pair <- x2 - x1
diff list(x1 - diff, x2 + diff) |>
keep(~in_bounds(.x, map))
}
# Get coordinates of every antenna of the given frequency
<- function(freq, map) {
get_freq_antennas <- which(map == freq, arr.ind = TRUE)
antennas split(antennas, row(antennas))
}
# Compute all antinodes of a given frequency in a given map
<- function(freq, map, f) {
get_all_antinodes <- get_freq_antennas(freq, map)
antennas
<- combn(antennas, 2)
pairs <- split(pairs, col(pairs))
pairs
|>
pairs map(~f(.x[[1]], .x[[2]], map)) |>
list_flatten() |>
unique()
}
Run antinode functions on puzzle input:
# Convert input to matrix format
<- input |>
mtx str_split("") |>
unlist() |>
matrix(nrow = length(input), byrow = TRUE)
# Find the distinct set of frequencies in the map
<- keep(
freqs unique(as.vector(mtx)),
~.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()
[1] 369
Part 2
Update the antinode function:
# Compute the updated antinodes of a given pair of antennas
<- function(x1, x2, map) {
antinode_set <- x2 - x1
diff <- list(x1, x2)
antinodes
<- 1
i while(in_bounds(x2 + i * diff, map)) {
<- c(antinodes, list(as.integer(x2 + i * diff)))
antinodes <- i + 1
i
}
<- 1
i while(in_bounds(x1 - i * diff, map)) {
<- c(antinodes, list(as.integer(x1 - i * diff)))
antinodes <- i + 1
i
}
antinodes }
Re-run puzzle input:
|>
freqs map(~get_all_antinodes(.x, mtx, antinode_set)) |>
list_flatten() |>
unique() |>
length()
[1] 1169