Advent of Code 2023 - Day 6Wait For It

R | Problem statement | Source code | Tags: Mathematics

Part 1

If I held the button for xx milliseconds to reach speed xx, then the distance traveled in tt milliseconds is (tx)x(t - x)\cdot x. I need this to be more than dd. Rearranging gives x2tx+d<0x^2 - tx + d < 0, which means I can't win if Δ=t24d<0\Delta = t^2 - 4d < 0. Otherwise, I need (tΔ)/2<x<(t+Δ)/2(t - \sqrt{\Delta})/2 < x < (t + \sqrt{\Delta})/2. I just need to count the integers in this range.

The number of integers in the exclusive range (a,b)(a, b) is max(0,ba1)\max(0, \lceil b \rceil - \lfloor a \rfloor - 1). Why? Because [b,)[\lceil b \rceil, \infty) and (,a](-\infty, \lfloor a \rfloor] are the integers outside the range.

winning_vals <- function(row) {
t <- row[["times"]]
d <- row[["distances"]]
discriminant <- t^2 - 4 * d
if (discriminant < 0) {
return(0)
}
x1 <- (t - sqrt(discriminant)) / 2
x2 <- (t + sqrt(discriminant)) / 2
ceiling(x2) - floor(x1) - 1
}
R

Part 1 is the product of applying this function to each row.

Part 2

Because we aren't doing simulations, just calculations, making the input larger doesn't change anything. Previously it was wins <- apply(parsed_data, 1, winning_vals); now it's wins <- winning_vals(list(times = times, distances = distances)).