library(tidyverse)
library(here)
What is going on with these puzzles?! Difficulty dropped quite a bit again for the even day puzzles.
Part 1
Let’s recap on the puzzle prompt.
Determine the number of ways you could beat the record in each race. What do you get if you multiply these numbers together?
Let’s first start off with reading in the puzzle input and tidy the data.
<- read_lines(
data here('posts', 'aoc-2023-d6', 'puzzle-input.txt')
)
<- data |>
data as_tibble() |>
separate(value, c('type', 'value'), sep = ': ') |>
mutate(
value = str_trim(value),
value = str_split(value, ' '),
value = map(value, \(x) as.numeric(x) |> na.omit())
|>
) unnest(value) |>
mutate(race = rep(1:4, 2)) |>
pivot_wider(names_from = type, values_from = value)
<- data |> janitor::clean_names()
data
data
# A tibble: 4 × 3
race time distance
<int> <dbl> <dbl>
1 1 53 333
2 2 83 1635
3 3 72 1289
4 4 88 1532
The idea of this puzzle is that we have 4 toy boat races that we need to figure out the number of ways that we can beat the record for the boat races. For each toy boat, we can hold the button down to make the boat go faster. The speed is directly correlated with the amount of time the button is held e.g. 1 milisecond = 1 milimeter/milisecond, 2 milisecond = 2 milimeter/milisecond, etc. However for each milisecond we hold the button down, the time will go against the amount of time alotted to travel the distance. If we hold the button down for too long, then we won’t have time to travel. If we hold the button down for too short, then the boat won’t have any speed to travel the necessary distance to beat the record.
Let’s create a function that allows us to tabulate the button hold, dependent on the total time and the amount of time the button was held.
<- \(total_time, button_hold) {
calculate_total_distance <- button_hold
speed
<- total_time - button_hold
time_remaining <- speed * time_remaining
total_distance
total_distance
}
Let’s create a tibble with all possible amount of time to hold the button from 0 milisecond to the total time for each race. Now let’s tabulate the total distance traveled for all possible time the button was held. Finally let’s identify the rows, where the total distance traveled from our toy boat exceeeded the distance traveled for the record. We can then count the total rows for each record, and determine the product for the answer.
<- pmap(data, \(race, time, distance) {
res <- tibble(total_time = time,
temp button_hold = 0:time,
distance)
|>
temp mutate(total_distance = calculate_total_distance(total_time, button_hold)) |>
filter(total_distance > distance) |>
nrow()
})
res
[[1]]
[1] 38
[[2]]
[1] 18
[[3]]
[1] 5
[[4]]
[1] 41
|> unlist() |> prod() res
first attempt: 140220
Part 2
How many ways can you beat the record in this one much longer race?
The strategy for part 2 is identical for part 1, however now we have 1 single race instead of 4 races. We then calculate the total number of ways we can beat the record in this much longe race
<- read_lines(here('posts', 'aoc-2023-d6', 'puzzle-input.txt'))
data
<- data |>
data as_tibble() |>
separate(value, c('type', 'value'), sep = ': ') |>
mutate(
value = str_trim(value, side = 'both'),
value = str_remove_all(value, ' '),
value = as.numeric(value)
|>
) pivot_wider(names_from = type, values_from = value) |>
::clean_names()
janitor
data
# A tibble: 1 × 2
time distance
<dbl> <dbl>
1 53837288 3.33e14
<- tibble(
res total_time = data$time,
button_hold = 0:data$time,
distance = data$distance
)
res
# A tibble: 53,837,289 × 3
total_time button_hold distance
<dbl> <int> <dbl>
1 53837288 0 3.33e14
2 53837288 1 3.33e14
3 53837288 2 3.33e14
4 53837288 3 3.33e14
5 53837288 4 3.33e14
6 53837288 5 3.33e14
7 53837288 6 3.33e14
8 53837288 7 3.33e14
9 53837288 8 3.33e14
10 53837288 9 3.33e14
# ℹ 53,837,279 more rows
|>
res mutate(total_distance = calculate_total_distance(total_time, button_hold)) |>
filter(total_distance > distance) |>
nrow()
Reuse
Citation
@online{luu2023,
author = {Luu, Michael},
title = {Advent of {Code} 2023, {Day} 6},
date = {2023-12-07},
langid = {en}
}