Skip to content

Instantly share code, notes, and snippets.

@statzhero
Last active December 4, 2023 15:47
Show Gist options
  • Save statzhero/37cadac26569b9812fa03b173cdf0bc5 to your computer and use it in GitHub Desktop.
Save statzhero/37cadac26569b9812fa03b173cdf0bc5 to your computer and use it in GitHub Desktop.
Advent of Code day 3 solution
library(tidyverse)
n_hood <- c(141,140,139,1,-1,-139,-140,-141)
get_nhood <- function(x, lags = n_hood, fill = "x"){
collapse::flag(x, lags, fill = fill) |>
as_tibble() |>
unite("concat", sep = "") |>
pull(concat)
}
# prep
x <- read_lines("./inst/input03.txt") |>
str_replace_all("\\.", "x") |> # for lazy regex later
str_split("") |> unlist() |>
enframe("pos", "chr") |>
mutate(is_digit = str_detect(chr, "[0-9]")) |>
mutate(groups = consecutive_id(is_digit)) |>
mutate(nhood = if_else(is_digit, get_nhood(chr), NA)) |>
mutate(sym_close = str_detect(nhood, "[\\p{P}\\p{S}]")) |>
mutate(.by = groups, part_number = any(sym_close))
#--- part 1 ------------------------------------------------
x |>
filter(part_number) |>
mutate(.by = groups, decimal_value = as.numeric(chr) * 10^(n()-row_number())) |>
pull(decimal_value) |>
sum()
#--- part 2 ------------------------------------------------
detect_gear <- function(x){
# pain: must account for 1.1 as sep numbers
top <- str_count(str_sub(x, 1, 3), "\\d+")
left <- str_count(str_sub(x, 4, 4), "\\d")
right <- str_count(str_sub(x, 5, 5), "\\d")
bottom <- str_count(str_sub(x, 6, 8), "\\d+")
( top + left + right + bottom >= 2 )
}
gear_parts <- x |>
mutate(gear_hood = if_else(chr == "*", get_nhood(chr), NA)) |>
mutate(gear = detect_gear(gear_hood)) |>
mutate(part_1_loc = if_else(gear, row_number() - n_hood[str_locate(gear_hood, "\\d")[,1]], NA)) |>
mutate(part_2_loc = if_else(gear, row_number() - n_hood[str_locate(gear_hood, "\\d[x]*$")[,1]], NA)) |>
mutate(gear_part_1 = row_number() %in% part_1_loc) |>
mutate(.by = groups, gear_part_1 = part_number & any(gear_part_1)) |>
mutate(gear_part_2 = row_number() %in% part_2_loc) |>
mutate(.by = groups, gear_part_2 = part_number & any(gear_part_2))
get_gear_parts <- function(x, var, loc){
x |>
filter({{var}}) |>
summarize(.by = groups, {{var}} := sum(as.numeric(chr) * 10^(n()-row_number()))) |>
# pain: need to arrange by gears
bind_cols(x |> filter(gear) |> rowid_to_column("id") |> arrange({{loc}}) |> select(id)) |>
arrange(id) |>
pull({{var}})
}
gear_part_1 <- get_gear_parts(gear_parts, gear_part_1, part_1_loc)
gear_part_2 <- get_gear_parts(gear_parts, gear_part_2, part_2_loc)
sum(gear_part_1 * gear_part_2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment