# Libraries
library(tidyverse)
# Read input into a data frame and convert to indexed nested lists
<- read_table("../input/day13.txt", col_names = "txt") |>
df mutate(
row_id = row_number(),
group_id = floor((row_id - 1) / 2) + 1,
item_id = (row_id - 1) %% 2 + 1,
lst = map(txt, jsonlite::fromJSON, simplifyVector = FALSE)
)
Day 13
Advent of Code: Worked Solutions
Setup
Part 1
Define a function to compare nested lists:
<- function(a, b) {
compare_nested
# Compare if both inputs are numeric
if (is.numeric(a) & is.numeric(b)) {
if (a < b) return(-1)
if (a > b) return(1)
if (a == b) return(0)
}
# Compare if only one input is numeric
if (is.numeric(a) != is.numeric(b)) {
if (is.numeric(a))
return(compare_nested(list(a), b))
if (is.numeric(b))
return(compare_nested(a, list(b)))
}
# Compare if both inputs are lists
<- 1
i while (i <= min(length(a), length(b))) {
<- compare_nested(a[[i]], b[[i]])
result if (result %in% c(1, -1))
return(result)
<- i + 1
i
}# When all comparable values are equal, compare lengths
return(compare_nested(length(a), length(b)))
}
Sum the indices of packet pairs that are in order:
|>
df select(group_id, item_id, lst) |>
pivot_wider(
names_from = item_id,
names_prefix = "item_",
values_from = lst
|>
) mutate(comparison = map2_int(item_1, item_2, compare_nested)) |>
filter(comparison == -1) |>
pull(group_id) |>
sum()
[1] 5684
Part 2
Define a function to determine the pairwise order of nested lists:
<- function(lst) {
sort_nested <- length(lst)
n <- 1:n
indices
if (n == 0) return()
if (n == 1) return(indices)
# Bubble sort: loop through list and swap elements until sorted
repeat {
<- FALSE
swap_occurred for (i in 1:(n - 1)) {
<- which(indices == i)
j1 <- which(indices == i + 1)
j2 if (compare_nested(lst[[j1]], lst[[j2]]) == 1) {
<- i + 1
indices[j1] <- i
indices[j2] <- TRUE
swap_occurred
}
}if (!swap_occurred) break
}return(indices)
}
Add new flagged packets, sort all, and multiply flagged indices:
<- list("[[2]]", "[[6]]") |>
new_packets map(jsonlite::fromJSON, simplifyVector = FALSE) |>
as_tibble_col(column_name = "lst")
|>
df transmute(lst, flag = FALSE) |>
add_row(new_packets, flag = TRUE) |>
mutate(ord = sort_nested(lst)) |>
filter(flag) |>
pull(ord) |>
prod()
[1] 22932