Toggle the code
library(aochelpers)
# other options: aoc_input_data_frame(), aoc_input_matrix()
<- aoc_input_vector(6, 2023)
input head(input)
[1] "Time: 55 99 97 93"
[2] "Distance: 401 1485 2274 1405"
Ella Kaye
December 6, 2023
[1] "Time: 55 99 97 93"
[2] "Distance: 401 1485 2274 1405"
Calculate all possible distances we can travel in the race, depending on how long we hold the button, then find the product of the distances that beat the current record.
After the challenges of the past couple of days, today’s puzzle seems remarkably straight-forward.
Wrangle the data:
Function for number of ways to win one race, where the arguments are single elements of times
and records
:1
Now apply this to all races, and get their product. We need mapply()
rather than sapply()
since we’re iterating over more than one argument to num_ways_to_win()
After I completed this, I saw an interesting discussion on the Advent of Code channel in the R4DS Slack about using a quadratic equation to solve this. That’s an elegant approach. My approach can be considered ‘brute force’ in comparison, since it calculates all possible distances. But since it only takes 0.001 seconds to run in R, and takes advantage of R’s vectorisation, I’m satisfied with my approach.
As above, but for one much longer race.
─ Session info ───────────────────────────────────────────────────────────────
setting value
version R version 4.3.2 (2023-10-31)
os macOS Sonoma 14.1
system aarch64, darwin20
ui X11
language (EN)
collate en_US.UTF-8
ctype en_US.UTF-8
tz Europe/London
date 2023-12-06
pandoc 3.1.1 @ /Applications/RStudio.app/Contents/Resources/app/quarto/bin/tools/ (via rmarkdown)
quarto 1.4.515 @ /usr/local/bin/quarto
─ Packages ───────────────────────────────────────────────────────────────────
package * version date (UTC) lib source
aochelpers * 0.1.0.9000 2023-12-06 [1] local
sessioninfo * 1.2.2 2021-12-06 [1] CRAN (R 4.3.0)
[1] /Users/ellakaye/Library/R/arm64/4.3/library
[2] /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/library
──────────────────────────────────────────────────────────────────────────────
I obviously don’t need both hold_times
and move_speeds
but this made it slightly easier for me to reason about the situation.↩︎
---
title: "2023: Day 6"
date: 2023-12-6
author:
- name: Ella Kaye
categories: [base R, ⭐⭐]
draft: false
---
## Setup
[The original challenge](https://adventofcode.com/2023/day/6)
[My data](input){target="_blank"}
## Part 1
```{r}
#| echo: false
OK <- "2023" < 3000
# Will only evaluate next code block if an actual year has been substituted for the placeholder.
```
```{r}
#| eval: !expr OK
library(aochelpers)
# other options: aoc_input_data_frame(), aoc_input_matrix()
input <- aoc_input_vector(6, 2023)
head(input)
```
::: {.callout-note collapse="false" icon="false"}
## The crux of the puzzle
Calculate all possible distances we can travel in the race,
depending on how long we hold the button,
then find the product of the distances that beat the current record.
:::
After the challenges of the past couple of days,
today's puzzle seems remarkably straight-forward.
Wrangle the data:
```{r}
input_numbers <- lapply(input, aochelpers::extract_numbers)
times <- input_numbers[[1]]
records <- input_numbers[[2]]
```
Function for number of ways to win one race,
where the arguments are single elements of `times` and `records`:^[I obviously don't need both `hold_times` and `move_speeds` but this made it slightly easier for me to reason about the situation.]
```{r}
num_ways_to_win <- function(time, record) {
hold_times <- move_speeds <- seq_len(time)
move_times <- time - hold_times
distances <- move_times * move_speeds
sum(distances > record)
}
```
Now apply this to all races, and get their product.
We need `mapply()` rather than `sapply()` since we're iterating over more than one argument to `num_ways_to_win()`
```{r}
mapply(num_ways_to_win, times, records) |>
prod()
```
After I completed this, I saw an interesting discussion on the Advent of Code channel in the R4DS Slack about using a quadratic equation to solve this.
That's an elegant approach. My approach can be considered 'brute force' in comparison, since it calculates all possible distances.
But since it only takes 0.001 seconds to run in R, and takes advantage of R's vectorisation, I'm satisfied with my approach.
## Part 2
::: {.callout-note collapse="false" icon="false"}
## The crux of the puzzle
As above, but for one much longer race.
:::
```{r}
time <- paste(times, collapse="") |> as.numeric()
record <- paste(records, collapse="") |> as.numeric()
num_ways_to_win(time, record)
```
##### Session info {.appendix}
<details><summary>Toggle</summary>
```{r}
#| echo: false
library(sessioninfo)
# save the session info as an object
pkg_session <- session_info(pkgs = "attached")
# get the quarto version
quarto_version <- system("quarto --version", intern = TRUE)
# inject the quarto info
pkg_session$platform$quarto <- paste(
system("quarto --version", intern = TRUE),
"@",
quarto::quarto_path()
)
# print it out
pkg_session
```
</details>