My 2022 Attempts
Day 1
Part 1
library(tidyverse)
input <- read_csv(here::here("2022", "day_01", "input_day01.txt"),
col_names = "calories", skip_empty_rows = FALSE)
input |>
mutate(empty = ifelse(is.na(calories), 1, 0),
elf = cumsum(empty)) |>
drop_na() |>
group_by(elf) |>
summarise(total_calories = sum(calories)) |>
slice_max(total_calories) |>
pull(total_calories) |>
print()[1] 72602
0.261 sec elapsed
Part 2
library(tidyverse)
input <- read_csv(here::here("2022", "day_01", "input_day01.txt"),
col_names = "calories", skip_empty_rows = FALSE)
input |>
mutate(empty = ifelse(is.na(calories), 1, 0),
elf = cumsum(empty)) |>
drop_na() |>
group_by(elf) |>
summarise(total_calories = sum(calories)) |>
slice_max(total_calories, n = 3) |>
summarise(total_calories = sum(total_calories)) |>
pull(total_calories) |>
print()[1] 207410
0.084 sec elapsed
Day 2
Didn’t have much time, so all I managed in the time was a series of case_when()’s. If I revisit I might use matrices instead.
Part 1
library(tidyverse)
input <- read_table(here::here("2022", "day_02", "input_day02.txt"),
col_names = c("x", "y"))
input |>
rename(opp = x,
me = y) |>
mutate(opp_base_score = case_when(opp == "A" ~ 1,
opp == "B" ~ 2,
opp == "C" ~ 3),
me_base_score = case_when(me == "X" ~ 1,
me == "Y" ~ 2,
me == "Z" ~ 3),
score_diff = me_base_score - opp_base_score,
me_turn_score = case_when(score_diff == -1 | score_diff == 2 ~ 0,
score_diff == 0 ~ 3,
score_diff == 1 | score_diff == -2 ~ 6),
me_game_score = me_base_score + me_turn_score) |>
summarise(total_score = sum(me_game_score)) |>
pull(total_score) |>
print()[1] 14531
0.038 sec elapsed
Part 2
library(tidyverse)
input <- read_table(here::here("2022", "day_02", "input_day02.txt"),
col_names = c("x", "y"))
input |>
rename(opp = x,
outcome = y) |>
mutate(opp_base_score = case_when(opp == "A" ~ 1,
opp == "B" ~ 2,
opp == "C" ~ 3),
me_turn_score = case_when(outcome == "X" ~ 0,
outcome == "Y" ~ 3,
outcome == "Z" ~ 6),
me_base_score = case_when(me_turn_score == 3 ~ opp_base_score,
me_turn_score == 0 &
opp_base_score > 1 ~ opp_base_score - 1,
me_turn_score == 0 & opp_base_score == 1 ~ 3,
me_turn_score == 6 &
opp_base_score < 3 ~ opp_base_score + 1,
me_turn_score == 6 & opp_base_score == 3 ~ 1),
me_game_score = me_turn_score + me_base_score) |>
summarise(total_score = sum(me_game_score)) |>
pull(total_score) |>
print()[1] 11258
0.021 sec elapsed
Day 3
Would have made for a nice exercise in Python, but who doesn’t love a good regex challenge? 😊
Part 1
library(tidyverse)
input <- read_table(here::here("2022", "day_03", "input_day03.txt"),
col_names = "rucksack")
priority_values <- tibble(char = c(letters, LETTERS)) |>
mutate(priority = seq(n()))
input |>
mutate(nitems = nchar(rucksack),
comp1 = str_sub(rucksack, 1, nitems/2),
comp2 = str_sub(rucksack, nitems/2 + 1, nitems),
comp1_regex = map_chr(strsplit(comp1, ""), str_c, collapse = "|"),
common = str_extract(comp2, comp1_regex)) |>
left_join(priority_values, by = c("common" = "char")) |>
summarise(sum = sum(priority)) |>
pull(sum) |>
print()[1] 7793
0.046 sec elapsed
Part 2
library(tidyverse)
input <- read_table(here::here("2022", "day_03", "input_day03.txt"),
col_names = "rucksack")
priority_values <- tibble(char = c(letters, LETTERS)) |>
mutate(priority = seq(n()))
input |>
mutate(group = rep(seq(unique(n())/3), each = 3)) |>
group_by(group) |>
summarise(group_items = str_c(rucksack, collapse = "-")) |>
separate(group_items, into = c("comp1", "comp2", "comp3")) |>
mutate(comp1_regex = map_chr(strsplit(comp1, ""), str_c, collapse = "|"),
common_12 = str_extract_all(comp2, comp1_regex),
comp12_regex = map_chr(common_12, str_c, collapse = "|"),
common_all = str_extract(comp3, comp12_regex)) |>
left_join(priority_values, by = c("common_all" = "char")) |>
summarise(sum = sum(priority)) |>
pull(sum) |>
print()[1] 2499
0.043 sec elapsed
Day 4
Part 1
library(tidyverse)
input <- read_table(here::here("2022", "day_04", "input_day04.txt"),
col_names = "pairs")
input |>
separate(pairs, sep = ",|\\-", into = c("section1_start","section1_end",
"section2_start", "section2_end")) |>
mutate(across(everything(), ~ as.numeric(.x)),
overlap_1_2 = section1_start >= section2_start &
section1_end <= section2_end,
overlap_2_1 = section2_start >= section1_start &
section2_end <= section1_end) |>
filter(overlap_1_2 | overlap_2_1) |>
nrow() |>
print()[1] 453
0.043 sec elapsed
Part 2
library(tidyverse)
input <- read_table(here::here("2022", "day_04", "input_day04.txt"),
col_names = "pairs")
input |>
separate(pairs, sep = ",|\\-", into = c("section1_start","section1_end",
"section2_start", "section2_end")) |>
mutate(across(everything(), ~ as.numeric(.x)),
section1 = map2(section1_start, section1_end, ~seq(.x,.y)),
section2 = map2(section2_start, section2_end, ~seq(.x,.y)),
intersect = map2(section1, section2, ~ intersect(.x, .y)),
n_overlapping = lengths(intersect)) |>
filter(n_overlapping > 0) |>
nrow() |>
print()[1] 919
0.071 sec elapsed
Day 5
Took some help from Anthony Durrant here, this one was difficult!
Part 1
library(tidyverse)
crates <- read_fwf(here::here("2022", "day_05", "input_day05.txt"),
col_positions = fwf_widths(widths = NA)) |>
janitor::clean_names() |>
filter(str_detect(x1, "\\[")) |>
separate(x1,
into = str_glue("stack_{seq(9)}"),
sep = c(seq(from = 4, to = 37, by = 4))) |>
mutate(across(everything(), ~ str_extract(.x, "[A-Z]"))) |>
as.list() |>
map(~ .x[grepl("[A-Z]", .x)])
steps <- read_delim(here::here("2022", "day_05", "input_day05.txt"), skip = 10,
col_names = c("action", "index", "f", "from", "t", "to")) |>
select(index, from, to) |>
mutate(across(c(from, to), ~ str_c("stack_", .x)))
rearrange_crates <- function(x, steps){
from <- steps$from
to <- steps$to
n <- steps$index
for(i in seq(n)) {
x[[to]] <- c(x[[from]][1], x[[to]])
x[[from]]<- tail(x[[from]], length(x[[from]])-1)
}
return(x)
}
reduce(rlist::list.parse(steps), rearrange_crates, .init = crates) |>
map_chr(~ .x[1]) |>
paste(collapse = "") |>
print()[1] "WHTLRMZRC"
0.371 sec elapsed
Part 2
library(tidyverse)
crates <- read_fwf(here::here("2022", "day_05", "input_day05.txt"),
col_positions = fwf_widths(widths = NA)) |>
janitor::clean_names() |>
filter(str_detect(x1, "\\[")) |>
separate(x1,
into = str_glue("stack_{seq(9)}"),
sep = c(seq(from = 4, to = 37, by = 4))) |>
mutate(across(everything(), ~ str_extract(.x, "[A-Z]"))) |>
as.list() |>
map(~ .x[grepl("[A-Z]", .x)])
steps <- read_delim(here::here("2022", "day_05", "input_day05.txt"), skip = 10,
col_names = c("action", "index", "f", "from", "t", "to")) |>
select(index, from, to) |>
mutate(across(c(from, to), ~ str_c("stack_", .x)))
rearrange_crates_pt2 <- function(x, steps){
from <- steps$from
to <- steps$to
n <- steps$index
x[[to]] <- c(x[[from]][seq(n)], x[[to]])
x[[from]]<- tail(x[[from]], length(x[[from]])-n)
return(x)
}
reduce(rlist::list.parse(steps), rearrange_crates_pt2, .init = crates) |>
map_chr(~ .x[1]) |>
paste(collapse = "") |>
print()[1] "GMPMLWNMG"
0.143 sec elapsed
Day 6
Actually one of the first ones without any {tidyverse} functions!
Part 1
input <- readLines(here::here("2022", "day_06", "input_day06.txt"))
strsplit(input, split = "")[[1]] |>
slider::slide_lgl(~ length(.x) == 4 & length(.x) == length(unique(.x)),
.before = 3) |>
(\(x) {which(x == TRUE)[1]})() |>
print()[1] 1300
0.046 sec elapsed
Part 2
input <- readLines(here::here("2022", "day_06", "input_day06.txt"))
strsplit(input, split = "")[[1]] |>
slider::slide_lgl(~ length(.x) == 14 & length(.x) == length(unique(.x)),
.before = 13) |>
(\(x) {which(x == TRUE)[1]})() |>
print()[1] 3986
0.027 sec elapsed
Day 7
First Python solution this year, with some help from Viliam Pucik
Part 1
from collections import defaultdict
from itertools import accumulate
lines = open('./2022/day_07/input_day07.txt').read().splitlines()
dirs = defaultdict(int)
for line in lines:
match line.split():
case "$", "cd", "/":
path = ["/"]
case "$", "cd", "..":
path.pop()
case "$", "cd", dir:
path.append(dir + "/")
case "$" | "dir", *_:
continue
case size, _:
for p in accumulate(path):
dirs[p] += int(size)
total_sizes = sum(size for size in dirs.values() if size <= 1e5)
print(total_sizes)1783610
0.013 seconds elapsed
Part 2
from collections import defaultdict
from itertools import accumulate
lines = open('./2022/day_07/input_day07.txt').read().splitlines()
dirs = defaultdict(int)
for line in lines:
match line.split():
case "$", "cd", "/":
path = ["/"]
case "$", "cd", "..":
path.pop()
case "$", "cd", dir:
path.append(dir + "/")
case "$" | "dir", *_:
continue
case size, _:
for p in accumulate(path):
dirs[p] += int(size)
dir_to_remove = min(size for size in dirs.values() if size >= dirs["/"] - 40e6)
print(dir_to_remove)4370655
0.010 seconds elapsed
Day 8
For-loops just feel more appropriate in Python, with help from nitekat
Part 1
lines = open('./2022/day_08/input_day08.txt').read().splitlines()
trees = [[*map(int, line)] for line in lines]
n = 2 * (len(trees[0]) + len(trees) - 2)
for y in range(1, len(trees) - 1):
for x in range(1, len(trees[0]) - 1):
tree = trees[y][x]
row = trees[y]
col = [i[x] for i in trees]
left = row[:x]
right = row[x + 1 :]
top = col[:y]
bottom = col[y + 1 :]
if tree > min(max(left), max(right), max(top), max(bottom)):
n += 1
print(n)1700
0.092 seconds elapsed
Part 2
lines = open('./2022/day_08/input_day08.txt').read().splitlines()
trees = [[*map(int, line)] for line in lines]
s = 0
w = len(trees[0])
h = len(trees)
for y in range(1, len(trees) - 1):
for x in range(1, len(trees[0]) - 1):
t = trees[y][x]
row = trees[y]
col = [i[x] for i in trees]
left = row[:x][::-1]
right = row[x + 1 :]
top = col[:y][::-1]
bottom = col[y + 1 :]
left_blocked = [i for i, v in enumerate(left) if v - t >= 0]
left_score = x if len(left_blocked) == 0 else left_blocked[0] + 1
right_blocked = [i for i, v in enumerate(right) if v - t >= 0]
right_score = w - x - 1 if len(right_blocked) == 0 else right_blocked[0] + 1
top_blocked = [i for i, v in enumerate(top) if v - t >= 0]
top_score = y if len(top_blocked) == 0 else top_blocked[0] + 1
bottom_blocked = [i for i, v in enumerate(bottom) if v - t >= 0]
bottom_score = h - y - 1 if len(bottom_blocked) == 0 else bottom_blocked[0] + 1
ss = left_score * right_score * top_score * bottom_score
if ss > s:
s = ss
print(s)470596
0.203 seconds elapsed
Day 9
Day 10
Part 1
library(tidyverse)
input <- read_table(here::here("2022", "day_10", "input_day10.txt"),
col_names = c("operation", "argument"))
input |>
replace_na(list(argument = 0)) |>
mutate(steps = case_when(str_detect(operation, "add") ~ 2,
str_detect(operation, "noop") ~ 1),
step_num_start = tail(accumulate(steps, `+`, .init = 1), -1) - steps,
x_reg = 1 + cumsum(argument),
x_reg_prev = c(1, head(x_reg, -1))) |>
uncount(steps) |>
rowid_to_column(var = "step_num") |>
select(step_num, x_reg_prev) |>
rename(x_reg = x_reg_prev) |>
filter(step_num %in% seq(20, n(), 40)) |>
summarise(total = sum(step_num * x_reg)) |>
pull(total) |>
print()[1] 14060
0.039 sec elapsed
Part 2
library(tidyverse)
input <- read_table(here::here("2022", "day_10", "input_day10.txt"),
col_names = c("operation", "argument"))
input |>
replace_na(list(argument = 0)) |>
mutate(steps = case_when(str_detect(operation, "add") ~ 2,
str_detect(operation, "noop") ~ 1),
step_num_start = tail(accumulate(steps, `+`, .init = 1), -1) - steps,
x_reg = 1 + cumsum(argument),
x_reg_prev = c(1, head(x_reg, -1))) |>
uncount(steps) |>
mutate(step_num = seq(1, n())) |>
select(step_num, x_reg_prev) |>
rename(x_reg = x_reg_prev) |>
mutate(x_pos = (step_num - 1) %% 40,
pixel_on = abs(x_pos - x_reg) < 2,
pixel = ifelse(pixel_on, "#", NA),
row_num = cumsum(x_pos == 0)) |>
group_by(row_num) |>
mutate(x = row_number()) |>
filter(pixel_on) |>
ggplot(aes(x = x, y = row_num)) +
geom_tile(fill = "#f2f2f2") +
geom_text(label = "#", color = "#b3b3b3", size = 4) +
scale_y_reverse() +
coord_equal() +
theme_void() +
theme(plot.margin = margin(rep(10,4), unit = "mm"),
plot.background = element_rect(fill = "#0f0f23"))
ggsave(here::here("2022", "day_10", "plot_day10_pt2.png"), last_plot(),
height = 3, width = 8, dpi = 300)0.342 sec elapsed
