Advent of Code 2023, Day 6

advent of code
Author

Michael Luu

Published

December 7, 2023

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.

data <- read_lines(
  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 <- data |> janitor::clean_names()

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.

calculate_total_distance <- \(total_time, button_hold) {
  speed <- button_hold
  
  time_remaining <- total_time - button_hold
  total_distance <- speed * time_remaining
  
  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.

res <- pmap(data, \(race, time, distance) {
  temp <- tibble(total_time = time,
                 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
res |> unlist() |> prod()

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

data <- read_lines(here('posts', 'aoc-2023-d6', 'puzzle-input.txt'))

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) |>
  janitor::clean_names()

data
# A tibble: 1 × 2
      time distance
     <dbl>    <dbl>
1 53837288  3.33e14
res <- tibble(
  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

BibTeX citation:
@online{luu2023,
  author = {Luu, Michael},
  title = {Advent of {Code} 2023, {Day} 6},
  date = {2023-12-07},
  langid = {en}
}
For attribution, please cite this work as:
Luu, Michael. 2023. “Advent of Code 2023, Day 6.” December 7, 2023.