-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday08.R
60 lines (49 loc) · 1.48 KB
/
day08.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
library(tidyverse)
# read the data
input <- read_fwf(
"data/2024/day08.txt",
col_positions = fwf_widths(
rep(1, nchar(read_lines("data/2024/day08.txt", n_max = 1)))
)
) |>
as.matrix()
# helper functions
is_in_bounds <- function(pos, max_val) {
all(pos > 0) && all(pos <= max_val)
}
# add antinodes based on spacing and bounds
expand_antinodes <- function(position, spacing, max_val) {
antinodes <- list(position)
while (is_in_bounds(position + spacing, max_val)) {
position <- position + spacing
antinodes <- append(antinodes, list(position))
}
bind_rows(antinodes)
}
# calculate antinodes for specific frequency
calculate_antinodes <- function(freq, input) {
coords <- which(input == freq, arr.ind = TRUE) |>
as_tibble()
antinodes <- list()
for (i in seq_len(nrow(coords))) {
for (j in seq_len(nrow(coords))) {
if (!all(coords[j, ] == coords[i, ])) {
spacing <- coords[j, ] - coords[i, ]
a1 <- coords[i, ] - spacing
a2 <- coords[j, ] + spacing
antinodes <- append(antinodes, list(a1, a2))
}
}
}
bind_rows(antinodes) |>
distinct() |>
filter(if_all(everything(), ~ .x > 0 & .x <= max(dim(input))))
}
# get all antinodes for the matrix
extract_all_antinodes <- function(input) {
unique_values <- setdiff(unique(as.vector(input)), ".")
map_dfr(unique_values, calculate_antinodes, input = input) |>
distinct()
}
# how many unique locations contain an antinode?
nrow(extract_all_antinodes(input))