2018-04: Repose Record

library(tidyverse)
library(data.table)
library(stringi)
dt <- readLines("input.txt")
pattern <- "\\[([0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2})\\] (.*)"
dt <- data.table(do.call(rbind, stri_match_all_regex(dt, pattern)))
colnames(dt) <- c("input", "time", "action")
dt$guard <- as.numeric(do.call(rbind, stri_match_all_regex(dt$action, "[0-9]{3,4}")))
dt$time <- as.POSIXct(dt$time)
dt$action <- ifelse(dt$action == "falls asleep", "asleep", "awake")
dt <- dt[order(time)] |> 
  fill(guard) |>
  select(-input) |>
  mutate(minute = minute(time), day = as.Date(time)) |>
  filter(hour(time) == 0)

Part 1

data.table("day" =
             rep(seq.Date(as.Date(min(dt$time)), 
                          as.Date(max(dt$time)), 
                          by = "day"), 
                 each = 60),
           "minute" = 0:59) |>
  left_join(dt, by = c("day", "minute")) |>
  select(-time) |>
  arrange(day, minute) |>
  fill(action, guard) |>
  filter(action == "asleep") |>
  dcast(guard ~ minute, value.var = "action", fun.aggregate = length) -> saved
saved %>%
  mutate(total = rowSums(.) - guard) |>
  filter(total == max(total)) |>
  select(-total) |>
  as.vector() |>
  unlist() -> vec

unname(vec["guard"] * as.numeric(names(which.max(vec[-1]))))
[1] 146622

Part 2

saved |>
  pivot_longer(cols = matches("[0-9]{1,2}"), names_to = "minute", values_to = "times") |>
  filter(times == max(times)) |>
  mutate(value = guard * as.numeric(minute)) |>
  pull(value)
[1] 31848