1 Setup
1.1 Libraries
library(httr)
library(xml2)
library(magrittr)
library(dplyr)
library(purrr)
library(stringr)
1.2 Retrieve Data from AoC
session_cookie <- set_cookies(session = keyring::key_get("AoC-GitHub-Cookie"))
base_url <- paste0("https://adventofcode.com/", params$year, "/day/", params$task_nr)
puzzle <- GET(base_url,
session_cookie) %>%
content(encoding = "UTF-8") %>%
xml_find_all("///article") %>%
lapply(as.character)
parse_puzzle_data <- function(text_block = readClipboard()) {
if (length(text_block) == 1L) {
text_block <- text_block %>%
str_split("\n") %>%
extract2(1L) %>%
keep(nzchar)
}
text_block %>%
str_split(",") %>%
extract2(1L)
}
puzzle_data <- local({
GET(paste0(base_url, "/input"),
session_cookie) %>%
content(encoding = "UTF-8") %>%
parse_puzzle_data()
})
2 Puzzle Day 11
2.1 Part 1
2.1.1 Description
— Day 11: Hex Ed —
Crossing the bridge, you’ve barely reached the other side of the stream when a program comes up to you, clearly in distress. “It’s my child process,” she says, “he’s gotten lost in an infinite grid!”
Fortunately for her, you have plenty of experience with infinite grids.
Unfortunately for you, it’s a hex grid.
The hexagons (“hexes”) in this grid are aligned such that adjacent hexes can be found to the north, northeast, southeast, south, southwest, and northwest:
\ n /
nw +--+ ne
/ \
-+ +-
\ /
sw +--+ se
/ s \
You have the path the child process took. Starting where he started, you need to determine the fewest number of steps required to reach him. (A “step” means to move from the hex you are in to any adjacent hex.)
For example:
-
ne,ne,ne
is3
steps away. -
ne,ne,sw,sw
is0
steps away (back where you started). -
ne,ne,s,s
is2
steps away (se,se
). -
se,sw,se,sw,sw
is3
steps away (s,s,sw
).
2.1.2 Solution
To account for the fact that the fields are hexagons, we encode straight steps by
2 / 0
and 0 / 2
(and their negative counterpart) while diagonal steps are encoded
by 1 / 1
(and all combinations with negative step sizes).
The final position is then simply the sum of the moves and we end up at some coordinates. To count the number for steps for this coordinate, we take the smaller of these two values (taken as absolute values) which would indicate the number of diagonal steps. Then we substract this number from the other position and divide by 2 which counts straight steps.
count_moves <- function(dirs) {
dir <- expand.grid(
row = -1:1,
col = -1:1
) %>%
set_rownames(c("nw", "w", "sw", "n", "x", "s", "ne", "e", "se")) %>%
as.matrix()
dir[, 1L] <- ((dir[, 2L] == 0) + 1L) * dir[, 1L]
dir[, 2L] <- ((dir[, 1L] == 0) + 1L) * dir[, 2L]
final_pos <- dir[dirs, , drop = FALSE] %>%
colSums()
diagonal_moves <- min(abs(final_pos))
straight_moves <- abs(final_pos) %>%
range() %>%
diff() %>%
divide_by(2L)
diagonal_moves + straight_moves
}
count_moves(puzzle_data)
## [1] 722
2.2 Part 2
2.2.1 Description
— Part Two —
How many steps away is the furthest he ever got from his starting position?
2.2.2 Solution
For the second part, we have to keep track about the intermediate steps and return the maximum distance as per the same logic.
count_furthest_move <- function(dirs) {
dir <- expand.grid(
row = -1:1,
col = -1:1
) %>%
set_rownames(c("nw", "w", "sw", "n", "x", "s", "ne", "e", "se")) %>%
as.matrix()
dir[, 1L] <- ((dir[, 2L] == 0) + 1L) * dir[, 1L]
dir[, 2L] <- ((dir[, 1L] == 0) + 1L) * dir[, 2L]
dir <- dir[dirs, , drop = FALSE]
pos <- cbind(0L, 0L)
max_moves <- -Inf
for (step in 1:nrow(dir)) {
pos <- pos + dir[step, , drop = FALSE]
diagonal_moves <- min(abs(pos))
straight_moves <- abs(pos) %>%
range() %>%
diff() %>%
divide_by(2L)
if (diagonal_moves + straight_moves > max_moves) {
max_moves <- diagonal_moves + straight_moves
}
}
max_moves
}
count_furthest_move(puzzle_data)
## [1] 1551