Advent of Code with data.table: Week One

tutorials
community
Author

Kelly Bodwin

Published

December 7, 2024

Happy December, R friends!

One of my favorite traditions in the R community is the Advent of Code, a series of puzzles released at midnight EST from December 1st through 25th, to be solved through programming in the language of your choosing. I usually do a few of them each year, and once tried to do every single one at the moment it released!

This year, I know I won’t be able to do it daily, but I’m going to do as many as I can using just data.table solutions.

I’ll allow myself to use other packages when there isn’t any data.table equivalent, but my solutions must be as data.table-y as possible.

I’m going to abuse the blog post structure and update this file throughout the week.

library(data.table)

December 1st

Part One

d1 <- fread("day1_dat1.txt")
d1[, V1 := sort(V1)]
d1[, V2 := sort(V2)]
d1[, diff := abs(V1-V2)]

sum(d1$diff)
[1] 2815556

Part Two

d1[, similarity := sum(V1 == d1$V2)*V1, by = V1]

sum(d1$similarity)
[1] 23927637

December 2nd

Part One

d1 <- fread("day2_dat1.txt", fill = TRUE)
check_report <- function(vec) {
  
  vec <- na.omit(vec)
  
  has_neg <- vec < 0
  has_pos <- vec > 0
  
  inc_dec <- sum(has_neg) == length(vec) | sum(has_pos) == length(vec)

  too_big <- max(abs(vec)) > 3
  
  return(inc_dec & !too_big)
}
d1t <- transpose(d1)
deltas <- d1t[-nrow(d1t)] - d1t[2:nrow(d1t)]

res <- apply(deltas, 2, "check_report")

sum(res)
[1] 479

Part Two

test_reports <- function(dat) {

  deltas <- dat[-nrow(dat)] - dat[2:nrow(dat)]

  res <- apply(deltas, 2, "check_report")

  res
}
res <- test_reports(d1t)

for (i in 1:nrow(d1t)) {
  
  res <- res | test_reports(d1t[-i,])
  
  
}

sum(res)
[1] 531

Just for fun

I found the use of apply deeply unsatisfying, even though it was fast, so just for fun:

d1t <- transpose(d1)
deltas <- d1t[-nrow(d1t)] - d1t[2:nrow(d1t)]

is_not_pos <- deltas <= 0
is_not_neg <- deltas >= 0
is_big <- abs(deltas) > 3

res_inc <- colSums(is_not_neg | is_big, na.rm = TRUE)

res_dec <- colSums(is_not_pos | is_big, na.rm = TRUE)

sum(res_inc == 0) + sum(res_dec == 0)
[1] 479

Yay. :)

No matching items