library(tidyverse)
library(here)
Part 1
The complexity of this puzzle dropped a bit for Day 4. Definitely wasn’t as difficulty as Day 3.
Let’s again take a look at the prompt for the puzzle
Take a seat in the large pile of colorful cards. How many points are they worth in total?
The idea is that we have a whole bunch of scratch cards, with a set of winning numbers and your set of numbers. We need to identify the total number of matches for each card, and then calculate the points for each card.
We calculate the points by using the following formula.
- If there are no matches then the card is worth 0 points
- If there are 1 match then the card is worth 1 point
- If there are more than 1 match, then the card is worth 2 times the number of matches
Let’s first read in the data
<- read_lines(
data here('posts', 'aoc-2023-d4', 'puzzle-input.txt')
)
<- as_tibble(data)
data
data
# A tibble: 196 × 1
value
<chr>
1 Card 1: 61 73 92 28 96 76 32 62 44 53 | 61 17 26 13 92 5 73 29 53 42 62 4…
2 Card 2: 3 88 36 12 2 9 15 55 21 89 | 23 39 98 36 2 24 9 3 78 95 55 3…
3 Card 3: 96 44 52 56 82 89 73 50 9 68 | 39 71 64 32 13 57 56 67 34 84 51 5…
4 Card 4: 54 84 76 44 38 33 12 17 93 94 | 18 21 53 11 7 98 78 92 9 32 29 5…
5 Card 5: 8 11 33 98 37 80 39 76 53 91 | 82 35 27 29 50 73 24 4 5 53 93 6…
6 Card 6: 10 58 39 28 35 79 14 73 64 96 | 90 86 38 93 74 29 21 14 33 16 85 …
7 Card 7: 1 96 73 38 64 87 45 25 99 10 | 11 30 96 43 17 72 24 55 79 64 98 4…
8 Card 8: 24 3 23 50 58 35 57 51 22 2 | 95 50 22 75 27 57 72 25 12 61 82 1…
9 Card 9: 98 59 30 22 10 69 68 17 48 8 | 22 75 34 63 7 72 30 73 19 13 35 8…
10 Card 10: 82 32 48 60 17 85 97 22 26 87 | 33 49 81 29 70 8 74 45 97 68 36 7…
# ℹ 186 more rows
Now that the data is read in, let’s tidy the data up a bit. We’ll use the separate
function to split the data into the card and the value. We’ll then use str_extract
to extract the card number from the card string. We’ll then use separate
again to split the value into the winning numbers and the elf’s numbers. We’ll then use str_split
to split the winning numbers and elf’s numbers into a list of numbers. We’ll then use as.numeric
to convert the numbers from strings to numbers. We’ll then use na.omit
to remove any NA
values from the list of numbers.
<- data |>
data separate(value, c('card', 'value'), sep = ': ') |>
mutate(card = str_extract(card, '\\d+') |> as.numeric()) |>
separate(value, c('winning_numbers', 'elfs_numbers'), sep = ' \\| ') |>
mutate(winning_numbers = str_split(winning_numbers, ' ') |>
map(\(x) as.numeric(x)),) |>
mutate(winning_numbers = map(winning_numbers, \(x) na.omit(x)))
<- data |>
data mutate(
elfs_numbers = str_split(elfs_numbers, ' '),
elfs_numbers = map(elfs_numbers, \(x) as.numeric(x) |> na.omit())
)
data
# A tibble: 196 × 3
card winning_numbers elfs_numbers
<dbl> <list> <list>
1 1 <dbl [10]> <dbl [25]>
2 2 <dbl [10]> <dbl [25]>
3 3 <dbl [10]> <dbl [25]>
4 4 <dbl [10]> <dbl [25]>
5 5 <dbl [10]> <dbl [25]>
6 6 <dbl [10]> <dbl [25]>
7 7 <dbl [10]> <dbl [25]>
8 8 <dbl [10]> <dbl [25]>
9 9 <dbl [10]> <dbl [25]>
10 10 <dbl [10]> <dbl [25]>
# ℹ 186 more rows
Now that the data is tidied up, let’s calculate the number of matches for each card. We’ll use the intersect
function to calculate the number of matches. We’ll then use length
to calculate the number of matches. We’ll then use map_int
to calculate the points for each card, based on the above rule.
<- \(winning_numbers, elfs_numbers) {
calculate_matches intersect(elfs_numbers, winning_numbers) |>
length()
}
<- data |>
data rowwise() |>
mutate(
matches = calculate_matches(winning_numbers, elfs_numbers)
|>
) ungroup()
<- data |>
data mutate(points = map_int(matches, \(matches) {
if (matches == 0) {
<- 0
points else if (matches == 1) {
} <- 1
points else if (matches > 1) {
} <- 2 ^ (matches - 1)
points
}
return(points)
}))
data
# A tibble: 196 × 5
card winning_numbers elfs_numbers matches points
<dbl> <list> <list> <int> <int>
1 1 <dbl [10]> <dbl [25]> 10 512
2 2 <dbl [10]> <dbl [25]> 10 512
3 3 <dbl [10]> <dbl [25]> 1 1
4 4 <dbl [10]> <dbl [25]> 1 1
5 5 <dbl [10]> <dbl [25]> 2 2
6 6 <dbl [10]> <dbl [25]> 3 4
7 7 <dbl [10]> <dbl [25]> 10 512
8 8 <dbl [10]> <dbl [25]> 10 512
9 9 <dbl [10]> <dbl [25]> 5 16
10 10 <dbl [10]> <dbl [25]> 2 2
# ℹ 186 more rows
Finally we just add up the points, and we have the answer
sum(data$points)
Reuse
Citation
@online{luu2023,
author = {Luu, Michael},
title = {Advent of {Code} 2023, {Day} 4},
date = {2023-12-05},
langid = {en}
}