2018-04: Repose Record

library(tidyverse)
── Attaching packages ─────────────────────────────────────── tidyverse 1.3.2 ──
✔ ggplot2 3.4.0      ✔ purrr   0.3.5 
✔ tibble  3.1.8      ✔ dplyr   1.0.10
✔ tidyr   1.2.1      ✔ stringr 1.4.1 
✔ readr   2.1.3      ✔ forcats 0.5.2 
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
library(data.table)

Attaching package: 'data.table'

The following objects are masked from 'package:dplyr':

    between, first, last

The following object is masked from 'package:purrr':

    transpose
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