suppressPackageStartupMessages({
library(tidyverse)
library(httr2)
})
adventofcode_input <- \(
year, day, what = c("data.frame", "character", "matrix"), input = NULL
) {
if (is.null(input)) {
session <- Sys.getenv("ADVENT_SESSION")
if (session == "") {
stop("Must set ADVENT_SESSION in .Renviron")
}
url <- paste0("https://adventofcode.com/", year, "/day/", day, "/input")
tryCatch({
res <- request(url) |>
req_cookies_set(session = session) |>
req_perform() |>
resp_body_string(encoding = "UTF-8")
},
error = \(e) stop("Error getting the input file")
)
} else {
res <- input
}
if(what[1] == "character") {
return(res)
}
df <- data.frame(x = res |> strsplit("\n") |> unlist())
if(what[1] == "data.frame") {
return(df)
}
if(what[1] == "matrix") {
ret <- df$x |>
stringr::str_split("")
m <- do.call(rbind, ret)
return(m)
}
}Day 5
AdventOfCode > 2024
Part 1
test <- "47|53
97|13
97|61
97|47
75|29
61|13
75|53
29|13
97|29
53|29
61|53
97|53
61|29
47|13
75|47
97|75
47|61
75|61
47|29
75|13
53|13
75,47,61,53,29
97,61,53,29,13
75,29,13
75,97,47,61,53
61,13,29
97,13,75,29,47"
input <- adventofcode_input(what = "data.frame", input = test)
rules <-
input |>
filter(row_number() < which(x == "")) |>
separate_wider_delim(x, "|", names_sep = "") |>
print()# A tibble: 21 × 2
x1 x2
<chr> <chr>
1 47 53
2 97 13
3 97 61
4 97 47
5 75 29
6 61 13
7 75 53
8 29 13
9 97 29
10 53 29
# ℹ 11 more rows
updates <- input |>
filter(row_number() > which(x == "")) |>
mutate(
x = map(x, \(x) x |>
str_split_1(",") |>
as.numeric()
)
) |>
pull(x)
n_incorrect_rules <- \(u, rules) {
rules |>
filter((x1 %in% u) & (x2 %in% u)) |>
rowwise() |>
mutate(posx1 = which(u == x1), posx2 = which(u == x2)) |>
ungroup() |>
filter(posx1 > posx2) |>
nrow()
}
sum(map_dbl(updates, \(i) {
if(n_incorrect_rules(i, rules) == 0) {
i[(1+length(i))/2]
} else {
0
}
}))[1] 143
input <- adventofcode_input(2024, 5, what = "data.frame")
rules <-
input |>
filter(row_number() < which(x == "")) |>
separate_wider_delim(x, "|", names_sep = "")
updates <- input |>
filter(row_number() > which(x == "")) |>
mutate(
x = map(x, \(x) x |>
str_split_1(",") |>
as.numeric()
)
) |>
pull(x)
n_incorrect_rules <- \(u, rules) {
rules |>
filter((x1 %in% u) & (x2 %in% u)) |>
rowwise() |>
mutate(posx1 = which(u == x1), posx2 = which(u == x2)) |>
ungroup() |>
filter(posx1 > posx2) |>
nrow()
}
sum(map_dbl(updates, \(i) {
if(n_incorrect_rules(i, rules) == 0) {
i[(1+length(i))/2]
} else {
0
}
}))[1] 5732
Part 2
test <- "47|53
97|13
97|61
97|47
75|29
61|13
75|53
29|13
97|29
53|29
61|53
97|53
61|29
47|13
75|47
97|75
47|61
75|61
47|29
75|13
53|13
75,47,61,53,29
97,61,53,29,13
75,29,13
75,97,47,61,53
61,13,29
97,13,75,29,47"
input <- adventofcode_input(what = "data.frame", input = test)
rules <-
input |>
filter(row_number() < which(x == "")) |>
separate_wider_delim(x, "|", names_sep = "")
updates <- input |>
filter(row_number() > which(x == "")) |>
mutate(
x = map(x, \(x) x |>
str_split_1(",") |>
as.numeric()
)
) |>
pull(x)
incorrect_rules <- \(u, rules) {
rules |>
filter((x1 %in% u) & (x2 %in% u)) |>
rowwise() |>
mutate(posx1 = which(u == x1), posx2 = which(u == x2)) |>
ungroup() |>
filter(posx1 > posx2)
}
n_incorrect_rules <- \(u, rules) {
incorrect_rules(u, rules) |>
nrow()
}
generate_permutations <- function(vec) {
n <- length(vec)
grid <- expand.grid(rep(list(vec), n))
valid_perms <- grid[apply(grid, 1, function(row) length(unique(row)) == n), ]
valid_perms |>
rowwise() |>
group_split() |>
map(as.numeric)
}
correct_update <- \(u, rules) {
candidates <- generate_permutations(u)
for(i in seq_along(candidates)) {
candidate <- candidates[[i]]
if(n_incorrect_rules(candidate, rules) == 0){
return(candidate)
}
}
stop("We didn't find a solution.")
}
# correct_update(c(61, 13, 29), rules)
# correct_update(c(97, 13, 75, 29, 47), rules)
sum(map_dbl(updates, \(i) {
incorrect <- incorrect_rules(i, rules)
if(nrow(incorrect) > 0) {
fixed <- correct_update(i, rules)
return(fixed[(1+length(fixed))/2])
}
0
}))[1] 123
input <- adventofcode_input(2024, 5, what = "data.frame")
rules <- input |>
filter(row_number() < which(x == "")) |>
separate_wider_delim(x, "|", names_sep = "")
updates <- input |>
filter(row_number() > which(x == "")) |>
mutate(x = map(x, \(x) x |> str_split_1(",") |> as.numeric())) |>
pull(x)
incorrect_rules <- \(u, rules) {
rules |>
filter((x1 %in% u) & (x2 %in% u)) |>
rowwise() |>
mutate(posx1 = which(u == x1), posx2 = which(u == x2)) |>
ungroup() |>
filter(posx1 > posx2)
}
correct_update <- \(u, rules) {
# print(u)
i <- 1
repeat {
to_fix <- incorrect_rules(u, rules)
if(nrow(to_fix) == 0) return(u)
current <- to_fix[1, ]
u[c(current$posx2, current$posx1)] <- u[c(current$posx1, current$posx2)]
i <- i + 1
# print(i)
}
}
# correct_update(c(97, 13, 75, 29, 47), rules)
sum(map_dbl(updates, \(i) {
incorrect <- incorrect_rules(i, rules)
if(nrow(incorrect) > 0) {
fixed <- correct_update(i, rules)
return(fixed[(1+length(fixed))/2])
}
0
}))[1] 4716