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)
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
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