Day 14

Advent of Code: Worked Solutions

About
Date

December 14, 2024

Setup

Import libraries:

library(tidyverse)
library(unglue)

Read input from file:

input <- read_lines("../input/day14.txt")

Extract numerical values from plaintext input:

df <- input |>
  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:

room_w <- 101
room_h <- 103

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.

pass_time <- function(df, seconds) {
  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:

get_safety_score <- function(df) {
  mid_w <- (room_w - 1) / 2
  mid_h <- (room_h - 1) / 2
  
  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)

cycle <- DescTools::LCM(room_w, room_h)

For each unique snapshot in the cycle, test for randomness vs structure in the X-Y coordinates.

simulations <- map_dfr(1:cycle, \(seconds) {
  new <- pass_time(df, seconds)
  c(secs = seconds, xvar = var(new$x), yvar = var(new$y))
})

simulations |> 
  arrange(xvar, yvar, secs) |> 
  filter(row_number() == 1) |> 
  pull(secs)