library(tidyverse)
library(unglue)
Day 14
Advent of Code: Worked Solutions
Setup
Import libraries:
Read input from file:
<- read_lines("../input/day14.txt") input
Extract numerical values from plaintext input:
<- input |>
df unglue_data("p={x},{y} v={vx},{vy}") |>
mutate(
across(everything(), parse_number),
robot_id = row_number(),
.before = everything()
)
Define parameters: dimensions of the room:
<- 101
room_w <- 103 room_h
Part 1
Define a function which gives the location of the robots after n seconds. Multiply n by the velocity, add to the current position, and modulo the room dimensions.
<- function(df, seconds) {
pass_time |>
df mutate(
x = (x + vx * seconds) %% room_w,
y = (y + vy * seconds) %% room_h
) }
Define a function to get the current safety factor by counting the number of robots in each quadrant of the room:
<- function(df) {
get_safety_score <- (room_w - 1) / 2
mid_w <- (room_h - 1) / 2
mid_h
|>
df mutate(
half_w = case_when(x < mid_w ~ 0, x > mid_w ~ 1),
half_h = case_when(y < mid_h ~ 0, y > mid_h ~ 1),
quadrant = half_w + 2 * half_h
|>
) drop_na(quadrant) |>
summarize(num_robots = n(), .by = quadrant) |>
pull(num_robots) |>
prod()
}
Compute safety score of puzzle input:
|>
df pass_time(100) |>
get_safety_score()
Part 2
First, find the cycle of seconds where the robots’ positions repeat (no more than the least common multiple of the room width and room height)
<- DescTools::LCM(room_w, room_h) cycle
For each unique snapshot in the cycle, test for randomness vs structure in the X-Y coordinates.
<- map_dfr(1:cycle, \(seconds) {
simulations <- pass_time(df, seconds)
new c(secs = seconds, xvar = var(new$x), yvar = var(new$y))
})
|>
simulations arrange(xvar, yvar, secs) |>
filter(row_number() == 1) |>
pull(secs)