# Libraries
library(tidyverse)
# Read input from file
<- read_lines("../input/day25.txt", skip_empty_rows = FALSE) input
Day 25
Advent of Code: Worked Solutions
Setup
Part 1
Convert input to lists of keys and locks by height:
<- input |>
groups enframe(name = NULL) |>
mutate(group_id = cumsum(value == ""), .before = everything()) |>
filter(value != "") |>
mutate(
col = str_split(value, ""),
row = row_number(),
.by = group_id
|>
) mutate(
type = case_when(row == 1 ~ if_else(str_detect(value, "#"), "lock", "key"))
|>
) fill(type, .direction = "down") |>
unnest_wider(col, names_sep = "") |>
mutate(group_id = str_c(type, "_", group_id)) |>
select(-c(value, row, type, row)) |>
group_split(group_id)
<- set_names(
groups
groups,map_chr(groups, ~ unique(pull(.x, group_id)))
)
Transpose data frames and count pin heights of each column:
<- groups |>
pins map(
~ .x |>
select(-group_id) |>
as.matrix() |>
t() |>
as_tibble() |>
transmute(height = rowSums(across(everything(), ~ .x == "#")) - 1) |>
pull(height)
)
<- keep_at(pins, ~ str_starts(.x, "lock"))
locks <- keep_at(pins, ~ str_starts(.x, "key")) keys
Compute maximum height for any given lock/key combo:
<- nrow(groups[[1]]) - 2 max_height
Cross all locks with all keys and check for overlapping pins:
expand_grid(lock = locks, key = keys) |>
mutate(fits = map2_lgl(lock, key, ~ max(.x + .y) <= max_height)) |>
pull(fits) |>
sum()
[1] 3495