My 2022 Solutions

Day 1

Part 1

input <- readLines("2022/01-input")
input <- as.numeric(input)

split(input, cumsum(is.na(input))) |>
  vapply(sum, na.rm = TRUE, FUN.VALUE = numeric(1)) |>
  max()
0.001 sec elapsed

Part 2

input <- readLines("2022/01-input")
input <- as.numeric(input)

split(input, cumsum(is.na(input))) |>
  vapply(sum, na.rm = TRUE, FUN.VALUE = numeric(1)) |>
  sort() |>
  tail(3) |>
  sum()
0.002 sec elapsed

Day 2

Part 1

input <- readLines("2022/02-input")

dict <- c(A = "rock", B = "paper", C = "scissors",
          X = "rock", Y = "paper", Z = "scissors")

you <- dict[substr(input, 1, 1)]
me <- dict[substr(input, 3, 3)]

mat <- matrix(
  c("tie", "lose", "win",
    "win", "tie", "lose",
    "lose", "win", "tie"),
  byrow = TRUE, ncol = 3,
  dimnames = list(c("rock", "paper", "scissors"),
                  c("rock", "paper", "scissors"))
)

scores <- c(win = 6, tie = 3, lose = 0, rock = 1, paper = 2, scissors = 3)

sum(scores[mat[cbind(me, you)]]) + sum(scores[me])
0.002 sec elapsed

Part 2

input <- readLines("2022/02-input")

dict <- c(A = "rock", B = "paper", C = "scissors",
          X = "lose", Y = "tie", Z = "win")

you <- dict[substr(input, 1, 1)]
me <- dict[substr(input, 3, 3)]

mat <- matrix(
  c("scissors", "rock", "paper",
    "paper", "scissors", "rock",
    "rock", "paper", "scissors"),
  byrow = TRUE, ncol = 3,
  dimnames = list(c("lose", "win", "tie"),
                  c("rock", "paper", "scissors"))
)
mat

scores <- c(win = 6, tie = 3, lose = 0, rock = 1, paper = 2, scissors = 3)

sum(scores[mat[cbind(me, you)]]) + sum(scores[me])
0.002 sec elapsed

Day 3

Part 1

library(purrr)

input <- readLines("2022/03-input") |>
  strsplit(split = "")

score <- c(letters, LETTERS)

common_split <- function(x) {
  half <- length(x) / 2
  intersect(
    head(x, half), tail(x, half)
  )
}

map_chr(input, common_split) |>
  match(score) |>
  sum()
0.012 sec elapsed

Part 2

library(purrr)

input <- readLines("2022/03-input") |>
  strsplit(split = "")

input_group <- split(input, rep(seq_len(length(input) / 3), each = 3))

score <- c(letters, LETTERS)

common_group <- function(x) {
  x[[1]] |>
    intersect(x[[2]]) |>
    intersect(x[[3]])
}

map_chr(input_group, common_group) |>
  match(score) |>
  sum()
0.002 sec elapsed

Day 4

Part 1

library(purrr)

input <- readLines("2022/04-input") |>
  strsplit("[-,]") |>
  map(as.integer)

contain <- function(x) {
  seq1 <- seq(x[1], x[2])
  seq2 <- seq(x[3], x[4])

  length(setdiff(seq1, seq2)) == 0 ||
  length(setdiff(seq2, seq1)) == 0
}

map_lgl(input, contain) |> sum()
0.028 sec elapsed

Part 2

library(purrr)

input <- readLines("2022/04-input") |>
  strsplit("[-,]") |>
  map(as.integer)

overlap <- function(x) {
  seq1 <- seq(x[1], x[2])
  seq2 <- seq(x[3], x[4])

  length(intersect(seq1, seq2)) > 0
}

map_lgl(input, overlap) |> sum()
0.014 sec elapsed

Day 5

Part 1

library(tidyverse)

input <- read_lines("2022/05-input")
delim <- which(input == "")

cargo <- input[seq(1, delim - 2)]
insts <- input[seq(delim + 1, length(input))] |>
  str_extract_all("[0-9]+") |>
  map(as.integer)

box_loc <- seq(1, (max(nchar(cargo)) + 1) / 4) * 4 - 2

stacks <- map(box_loc, ~ str_sub(cargo, .x, .x)) |>
  map(setdiff, c("", " ")) |>
  map(rev)

for (inst in insts) {
  from <- inst[2]
  to <- inst[3]
  amount <- inst[1]
  stacks[[to]] <- c(stacks[[to]], rev(tail(stacks[[from]], amount)))
  stacks[[from]] <- head(stacks[[from]], -amount)
}

purrr::map_chr(stacks, tail, 1) |> paste(collapse = "")
0.127 sec elapsed

Part 2

library(tidyverse)

input <- read_lines("2022/05-input")
delim <- which(input == "")

cargo <- input[seq(1, delim - 2)]
insts <- input[seq(delim + 1, length(input))] |>
  str_extract_all("[0-9]+") |>
  map(as.integer)

box_loc <- seq(1, (max(nchar(cargo)) + 1) / 4) * 4 - 2

stacks <- map(box_loc, ~ str_sub(cargo, .x, .x)) |>
  map(setdiff, c("", " ")) |>
  map(rev)

for (inst in insts) {
  from <- inst[2]
  to <- inst[3]
  amount <- inst[1]
  stacks[[to]] <- c(stacks[[to]], tail(stacks[[from]], amount))
  stacks[[from]] <- head(stacks[[from]], -amount)
}

purrr::map_chr(stacks, tail, 1) |> paste(collapse = "")
0.009 sec elapsed

Day 6

Part 1

input <- readLines("2022/06-input")
input <- strsplit(input, "")[[1]]

tar_length <- 4 # change to 14 for part 2
offset <- tar_length - 1

for (i in seq_len(length(input) - offset)) {
  if (length(unique(input[seq(i, i + offset)])) == tar_length) {
    break
  }
}
i + offset
0.008 sec elapsed

Part 2

input <- readLines("2022/06-input")
input <- strsplit(input, "")[[1]]

tar_length <- 14
offset <- tar_length - 1

for (i in seq_len(length(input) - offset)) {
  if (length(unique(input[seq(i, i + offset)])) == tar_length) {
    break
  }
}
i + offset
0.018 sec elapsed

Day 7

Part 1

library(tidyverse)

input <- readLines("2022/07-input")

disk <- list()
i <- 2
path <- c(NULL)

while (i <= length(input)) {
if (input[i] == "$ ls") {
  repeat {
    i <- i + 1
    if (i > length(input)) break
    if (str_detect(input[i], "^\\$")) break
    if (str_detect(input[i], "^dir")) {
      dir_name <- str_remove(input[i], "dir ")
      disk[[c(path, dir_name)]] <- list()
    } else {
      file_name <- str_remove(input[i], "\\d+ ")
      file_value <- str_extract(input[i], "\\d+") |> as.numeric()
      disk[[c(path, file_name)]] <- file_value
    }
  }
} else if (str_detect(input[i], "^\\$ cd \\.\\.")) {
  path <- path[-length(path)]
  i <- i + 1
} else if (str_detect(input[i], "^\\$ cd")) {
  next_dir <- str_remove(input[i], "^\\$ cd ")
  path <- c(path, next_dir)
  i <- i + 1
}
}

dir_sums <- list()

lists <- map_lgl(disk, is.list)
unused_folders <- as.list(names(disk)[lists])

repeat {
if (length(unused_folders) == 0) break
  path <- unused_folders[[1]]
  lists <- map_lgl(disk[[path]], is.list)
  if (any(lists)) {
    new_lists <- names(lists)[lists]
    for (new_list in new_lists) {
      unused_folders <- c(list(c(path, new_list)), unused_folders)
    }
  } else {
    dir_sum <- sum(unlist(disk[[path]]))
    dir_sums[paste(path, collapse = "_")] <- dir_sum
    disk[[path]] <- dir_sum
    unused_folders[[1]] <- NULL
  }
}

dir_sums$total <- sum(unlist(disk))
dir_sums <- unlist(dir_sums)

dir_sums[dir_sums < 100000] |>
  sum()
0.091 sec elapsed

Part 2

library(tidyverse)

input <- readLines("2022/07-input")

disk <- list()
i <- 2
path <- c(NULL)

while (i <= length(input)) {
  if (input[i] == "$ ls") {
    repeat {
      i <- i + 1
      if (i > length(input)) break
      if (str_detect(input[i], "^\\$")) break
      if (str_detect(input[i], "^dir")) {
        dir_name <- str_remove(input[i], "dir ")
        disk[[c(path, dir_name)]] <- list()
      } else {
        file_name <- str_remove(input[i], "\\d+ ")
        file_value <- str_extract(input[i], "\\d+") |> as.numeric()
        disk[[c(path, file_name)]] <- file_value
      }
    }
  } else if (str_detect(input[i], "^\\$ cd \\.\\.")) {
    path <- path[-length(path)]
    i <- i + 1
  } else if (str_detect(input[i], "^\\$ cd")) {
    next_dir <- str_remove(input[i], "^\\$ cd ")
    path <- c(path, next_dir)
    i <- i + 1
  }
}

dir_sums <- list()

lists <- map_lgl(disk, is.list)
unused_folders <- as.list(names(disk)[lists])

repeat {
  if (length(unused_folders) == 0) break
  path <- unused_folders[[1]]
  lists <- map_lgl(disk[[path]], is.list)
  if (any(lists)) {
    new_lists <- names(lists)[lists]
    for (new_list in new_lists) {
      unused_folders <- c(list(c(path, new_list)), unused_folders)
    }
  } else {
    dir_sum <- sum(unlist(disk[[path]]))
    dir_sums[paste(path, collapse = "_")] <- dir_sum
    disk[[path]] <- dir_sum
    unused_folders[[1]] <- NULL
  }
}

dir_sums$total <- sum(unlist(disk))
dir_sums <- unlist(dir_sums)

dir_sums[dir_sums >= (30000000 - (70000000 - dir_sums["total"]))] |>
  sort() |>
  head(1)
0.084 sec elapsed

Day 8

Part 1

library(tidyverse)

read_matrix <- function(path, sep = "", fill = NA, type = identity) {
  lines <- readLines(path)
  tokens <- strsplit(lines, sep)
  token_lengths <- lengths(tokens)
  res <- matrix(fill, nrow = length(lines), ncol = max(token_lengths))

  for (i in seq_along(lines)) {
    res[i, seq_len(token_lengths[i])] <- type(tokens[[i]])
  }
  res
}

input <- read_matrix("2022/08-input", type = as.integer)

res <- matrix(FALSE, nrow = nrow(input), ncol = ncol(input))

n_row <- nrow(input)
n_col <- ncol(input)

for (row in seq_len(n_row)) {
  for (col in seq_len(n_col)) {
    tree <- input[row, col]

    # Edge
    if (row == 1 || row == n_row || col == 1 || col == n_col) {
      res[row, col] <- TRUE
      next
    }

    # Above
    above <- input[seq(1, row - 1), col]
    if (all(tree > above)) {
      res[row, col] <- TRUE
      next
    }

    # below
    below <- input[seq(n_row, row + 1), col]
    if (all(tree > below)) {
      res[row, col] <- TRUE
      next
    }

    # left
    left <- input[row, seq(1, col - 1)]
    if (all(tree > left)) {
      res[row, col] <- TRUE
      next
    }

    # left
    right <- input[row, seq(n_col, col + 1)]
    if (all(tree > right)) {
      res[row, col] <- TRUE
      next
    }
  }
}

sum(res)
0.132 sec elapsed

Part 2

library(tidyverse)

read_matrix <- function(path, sep = "", fill = NA, type = identity) {
  lines <- readLines(path)
  tokens <- strsplit(lines, sep)
  token_lengths <- lengths(tokens)
  res <- matrix(fill, nrow = length(lines), ncol = max(token_lengths))

  for (i in seq_along(lines)) {
    res[i, seq_len(token_lengths[i])] <- type(tokens[[i]])
  }
  res
}

input <- read_matrix("2022/08-input", type = as.integer)

res <- matrix(0, nrow = nrow(input), ncol = ncol(input))

n_row <- nrow(input)
n_col <- ncol(input)

distances <- function(input, rows, cols) {
  above <- input[rows, cols]
  suppressWarnings(distance <- min(which(!(tree > above))))
  if (distance == Inf) {
    distance <- length(above)
  }
  distance
}

for (row in seq_len(n_row)) {
  for (col in seq_len(n_col)) {
    tree <- input[row, col]
    total <- 1

    # Above
    if (row > 1) {
      distance <- distances(input, seq(row - 1, 1), col)
      total <- total * distance
    }

    # below
    if (row < n_row) {
      distance <- distances(input, seq(row + 1, n_row), col)
      total <- total * distance
    }

    # left
    if (col > 1) {
      distance <- distances(input, row, seq(col - 1, 1))
      total <- total * distance
    }

    # right
    if (col < n_col) {
      distance <- distances(input, row, seq(col + 1, n_col))
      total <- total * distance
    }
    res[row, col] <- total
  }
}

max(res)
0.345 sec elapsed

Day 9

Day 10

Part 1

input <- readLines("2022/10-input")

X <- 1
cycles <- 0

for (i in input) {
  if (i == "noop") {
    cycles <- c(cycles, X)

  } else {
    cycles <- c(cycles, X)
    cycles <- c(cycles, X)
    val <- as.integer(substr(i, 6, nchar(i)))
    X <- X + val
  }
}

cycles <- cycles[-1]

index <- c(20, 60, 100, 140, 180, 220)

sum(cycles[index] * index)
0.004 sec elapsed

Part 2

Day 11

Day 12

Day 13

Day 14

Day 15

Day 16

Day 17

Day 18

Day 19

Day 20

Day 21

Day 22

Day 23

Day 24

Day 25