AdventOfCode > 2022
Part 1: In how many assignment pairs does one range fully contain the other?
I manually downloaded my personal day 4 input file as a logged user, and here I get the data.
── Attaching packages ─────────────────────────────────────── tidyverse 1.3.2 ──
✔ ggplot2 3.4.0 ✔ purrr 0.3.5
✔ tibble 3.1.8 ✔ dplyr 1.0.10
✔ tidyr 1.2.1 ✔ stringr 1.4.1.9000
✔ readr 2.1.3 ✔ forcats 0.5.2
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag() masks stats::lag()
# remotes::install_github("tidyverse/stringr", force = TRUE)
packageVersion("stringr") # 1.4.1.9000
data <-
read_csv(
here::here("2022/04_input"),
col_names = c("first", "second"),
show_col_types = FALSE
)
data %>% print(n = 30)
# A tibble: 1,000 × 2
first second
<chr> <chr>
1 1-93 2-11
2 26-94 26-94
3 72-92 48-88
4 36-37 37-52
5 2-98 1-98
6 1-83 1-84
7 74-79 76-76
8 66-85 66-86
9 6-73 6-73
10 31-57 30-58
11 1-98 1-98
12 28-47 55-97
13 29-71 70-72
14 40-53 40-53
15 14-71 39-71
16 19-98 18-94
17 94-96 81-95
18 79-98 79-97
19 52-66 60-61
20 2-3 8-89
21 53-59 59-83
22 79-81 3-80
23 14-84 84-92
24 90-90 7-89
25 10-76 11-76
26 9-31 10-12
27 8-8 8-72
28 2-97 1-96
29 3-33 2-94
30 3-5 4-99
# … with 970 more rows
I separate both columns:
data %>%
separate(first, c("first_start", "first_end"), sep = "-") %>%
separate(second, c("second_start", "second_end"), sep = "-")
# A tibble: 1,000 × 4
first_start first_end second_start second_end
<chr> <chr> <chr> <chr>
1 1 93 2 11
2 26 94 26 94
3 72 92 48 88
4 36 37 37 52
5 2 98 1 98
6 1 83 1 84
7 74 79 76 76
8 66 85 66 86
9 6 73 6 73
10 31 57 30 58
# … with 990 more rows
separate(first, c(“first_start”, “first_end”), sep = “-”) %>%
separate(second, c(“second_start”, “second_end”), sep = “-”)
I check if the first or second range in each row are fully contained one in another:
data %>%
separate(first, c("first_start", "first_end"), sep = "-") %>%
separate(second, c("second_start", "second_end"), sep = "-") %>%
mutate(across(everything(), as.numeric)) %>%
rowwise() %>%
mutate(fully_contain =
(first_start >= second_start & first_end <= second_end) |
(second_start >= first_start & second_end <= first_end)
)
# A tibble: 1,000 × 5
# Rowwise:
first_start first_end second_start second_end fully_contain
<dbl> <dbl> <dbl> <dbl> <lgl>
1 1 93 2 11 TRUE
2 26 94 26 94 TRUE
3 72 92 48 88 FALSE
4 36 37 37 52 FALSE
5 2 98 1 98 TRUE
6 1 83 1 84 TRUE
7 74 79 76 76 TRUE
8 66 85 66 86 TRUE
9 6 73 6 73 TRUE
10 31 57 30 58 TRUE
# … with 990 more rows
Here the full code with the result:
library(tidyverse)
fully_contain <- function(df) {
df %>%
mutate(across(everything(), as.numeric)) %>%
rowwise() %>%
mutate(fully_contain =
(first_start >= second_start & first_end <= second_end) |
(second_start >= first_start & second_end <= first_end)
) %>%
ungroup()
}
read_csv(
here::here("2022/04_input"),
col_names = c("first", "second"),
show_col_types = FALSE
) %>%
separate(first, c("first_start", "first_end"), sep = "-") %>%
separate(second, c("second_start", "second_end"), sep = "-") %>%
fully_contain() %>%
summarise(fully_contain = sum(fully_contain))
# A tibble: 1 × 1
fully_contain
<int>
1 503
Part 2: In how many assignment pairs do the ranges overlap?
overlap <- function(df) {
df %>%
mutate(across(everything(), as.numeric)) %>%
rowwise() %>%
mutate(overlap =
list(intersect(first_start:first_end, second_start:second_end))
) %>%
mutate(overlap = length(overlap) > 0) %>%
ungroup()
}
read_csv(
here::here("2022/04_input"),
col_names = c("first", "second"),
show_col_types = FALSE
) %>%
separate(first, c("first_start", "first_end"), sep = "-") %>%
separate(second, c("second_start", "second_end"), sep = "-") %>%
overlap() %>%
summarise(overlap = sum(overlap))
# A tibble: 1 × 1
overlap
<int>
1 827