# Libraries
library(tidyverse)
# Read input from file
<- read_lines("../input/day05.txt", skip_empty_rows = TRUE) input
Day 5
Advent of Code: Worked Solutions
Setup
Part 1
# Extract page ordering rules from input
<- input |>
rule_list keep(~ str_detect(.x, "\\|")) |>
as_tibble_col(column_name = "rule") |>
separate(rule, into = c("p1", "p2")) |>
mutate(rule_num = row_number(), .before = everything()) |>
mutate(across(c(p1, p2), parse_number))
# Extract page sequences from input
<- input |>
pages discard(~ str_detect(.x, "\\|")) |>
str_split(",") |>
map(parse_number) |>
as_tibble_col(column_name = "update")
# Sort a given vector by its applicable rules
<- function(seq) {
sort_by_rules <- rule_list |>
active_rules filter(p1 %in% seq & p2 %in% seq)
repeat {
<- FALSE
swap_occurred for (i in 1:nrow(active_rules)) {
<- filter(active_rules, row_number() == i)
rule <- which(seq == rule$p1)
idx1 <- which(seq == rule$p2)
idx2
if (idx1 > idx2) {
<- rule$p2
seq[[idx1]] <- rule$p1
seq[[idx2]] <- TRUE
swap_occurred
}
}if (!swap_occurred) return(seq)
}
}
# Sort all page sequences and extract the center page of each result
<- pages |>
output mutate(
resorted = map(update, sort_by_rules),
is_sorted = map2_lgl(update, resorted, identical),
center_page = map_int(resorted, ~ .x[(length(.x) + 1) / 2])
)
# For the properly-ordered updates, sum the center page numbers
|>
output filter(is_sorted) |>
pull(center_page) |>
sum()
[1] 6505
Part 2
# For the improperly-ordered updates, sum their sorted center pages
|>
output filter(!is_sorted) |>
pull(center_page) |>
sum()
[1] 6897