knitr::opts_chunk$set(echo = TRUE)

# Benchmark code chunks
knitr::knit_hooks$set(
  time = function(before, envir) {
    t <- proc.time()['elapsed']
    if(before) {
      envir$.elapsed <- t
    } else {
      paste(signif(t - envir$.elapsed), 'sec.')
    }
  }
)
library(assertthat)
library(dplyr)
library(here)
library(ggplot2)
library(knitr)

Day 1: Sonar Sweep

Part 1

# Read in data
dat <- scan(here("inst", "2021", "day1.txt"))

# Count the number of times the depth increases from the previous measurement
sum(diff(dat) > 0)

Part 2

# Sum depths in each window
index <- 1
summed <- c()
while((index + 2) <= length(dat)) {
  summed <- c(summed, sum(dat[index:(index + 2)]))
  index <- index + 1
}

# Count the number of times the depth increases from the previous measurement
sum(diff(summed) > 0)

Day 2: Dive!

Part 1


# Read in data
path <- here("inst", "2021", "day2.txt")
dat <- read_day2(path)

# Calculate the horizontal position and depth and multiply them together
dive(dat)

Part 2


dive2(dat)

Day 3: Binary Diagnostic

Part 1


# Read in data
path <- here("inst", "2021", "day3.txt")
dat <- read_day3(path)

# Calculate power consumption
power_consumption(dat)

Part 2


# Calculate oxygen generator and CO2 scrubber ratings
oxygen_generator_rating <- rating(dat, "oxygen")
CO2_scrubber_rating <- rating(dat, "CO2")

# Calculate life support rating
oxygen_generator_rating * CO2_scrubber_rating

Day 4: Giant Squid

Part 1


# Read in data
path <- here("inst", "2021", "day4.txt")
numbers <- get_numbers(path)
boards <- get_boards(path)

# Play bingo
play_bingo(numbers, boards)

Part 2


# Play bingo
losers <- lose_bingo(numbers, boards)
tail(losers)

Day 5: Hydrothermal Venture

Part 1


path <- here("inst", "2021", "day5.txt")
coordinates <- read_day5(path)

# Find points where at least two lines overlap
track_vents(coordinates)

Part 2


# Find points where at least two lines overlap
track_vents2(coordinates)

Day 6: Lanternfish

Part 1


# Read in data
path <- here("inst", "2021", "day6.txt")
dat <- read_day6(path)

# How many lanternfish would there be after 80 days?
simulate_lanternfish(dat)

Part 2

It takes too much memory to simulate individual fish in a vector, so generate a frequency table instead.


# How many lanternfish would there be after 256 days?
simulate_lanternfish2(dat)

Day 7: The Treachery of Whales

Part 1


# Read in data
path <- here("inst", "2021", "day7.txt")
dat <- read_day7(path)

# How much fuel must they spend to align to that position?
track_crabs(dat)

Part 2


# How much fuel must they spend to align to that position?
track_crabs2(dat)

Day 8: Seven Segment Search

Part 1


# Read in data
path <- here("inst", "2021", "day8.txt")
dat <- read_day8(path)

# How many times do digits 1, 4, 7, or 8 (length 2, 4, 3, and 7) appear?
count_digits(dat)

Part 2


# What do you get if you add up all of the output values?
decode_segments(dat)

Day 9: Smoke Basin

Part 1


# Read in data
path <- here("inst", "2021", "day9.txt")
dat <- read_day9(path)

# What is the sum of the risk levels of all low points on your heightmap?
lowest_points <- low_points(dat)
sum(lowest_points$risk)

Part 2


# Multiply together the sizes of the three largest basins
survey_basins(dat, lowest_points)

Day 10: Syntax Scoring

Part 1


# Read in data
path <- here("inst", "2021", "day10.txt")
dat <- read_day10(path)

# Find the first illegal character in each corrupted line of the navigation
# subsystem. What is the total syntax error score for those errors?
tmp <- syntax_score(dat)
tmp$total

Part 2


# Find the completion string for each incomplete line, score the completion
# strings, and sort the scores. What is the middle score?
remove_lines <- tmp$remove_lines
syntax_score2(dat, remove_lines)

Day 11: Dumbo Octopus

Part 1


# Read in data
test <- here("inst", "2021", "day11-test.txt")
path <- here("inst", "2021", "day11.txt")

test_dat <- read_day11(test)
dat <- read_day11(path)

# Test simulation
assertthat::assert_that(simulate_octopus(test_dat) == 1656)
# Given the starting energy levels of the dumbo octopuses in your cavern,
# simulate 100 steps. How many total flashes are there after 100 steps?
simulate_octopus(dat)

Part 2


# What is the first step during which all octopuses flash?
simulate_octopus2(dat)

Day 12: Passage Pathing

Part 1


# Read in data
path <- here("inst", "2021", "day12.txt")
dat <- read_day12(path)

# How many paths through this cave system are there that visit small caves at
# most once?
cave_routes(dat)

Part 2

We have to use a different method for Part 2, since it takes too long to calculate the number of routes.


# If we visit a single small cave twice, how many paths through this cave
# system are there?
cave_routes2(dat)

Day 13: Transparent Origami

Part 1


# Read in data
path <- here("inst", "2021", "day13.txt")
dat <- read_day13(path)

paper <- origami_paper(dat)
instructions <- origami_instructions(dat)

# How many dots are visible after completing just the first fold instruction on
# your transparent paper?
result <- fold_left(paper, instructions[1,]$value)
sum(result > 0)

Part 2


# What code do you use to activate the infrared thermal imaging camera system?
simulate_origami(paper, instructions)

Day 14: Extended Polymerization

Part 1


# Read in data
test <- here("inst", "2021", "day14-test.txt")
path <- here("inst", "2021", "day14.txt")

# Read in polymer template
test_template <- get_template(test)
template <- get_template(path)

# Read in pair insertion rules
test_rules <- get_rules(test)
rules <- get_rules(path)

# Run simulation
assertthat::assert_that(polymerization(test_template, test_rules, 10) == 1588)
# What do you get if you take the quantity of the most common element and
# subtract the quantity of the least common element?
polymerization(template, rules, 10)

Part 2

The second part asks for 40 iterations, which would take far too long using the same method used in part 1 (keeping track of an ever-growing string). So instead, we count the frequency of each pair.


# Apply 40 steps of pair insertion to the polymer template and find the
# most and least common elements in the result
assertthat::assert_that(
  polymerization2(test_template, test_rules, 40) == 2188189693529)
# What do you get if you take the quantity of the most common element
# and subtract the quantity of the least common element?
polymerization2(template, rules, 40) |> 
  format(scientific = FALSE)

Day 15: Chiton

Day 16: Packet Decoder

Day 17: Trick Shot

Part 1


# Read in data
path <- here("inst", "2021", "day17.txt")

dat <- read_day17(path)
xrange <- dat$xrange
yrange <- dat$yrange

# Find the initial velocity that causes the probe to reach the highest y
# position and still eventually be within the target area after any step
simulate_launch(xrange, yrange)

Part 2


velocities <- find_possibilities(xrange, yrange)
results <- simulate_launch2(velocities, xrange, yrange)

# Find the initial velocity that causes the probe to reach the highest y
# position and still eventually be within the target area after any step
results |>
  dplyr::filter(y_max == max(y_max))

# What is the highest y position it reaches on this trajectory?
results |>
  dplyr::filter(y_max == max(y_max)) |>
  dplyr::pull(y_max) |>
  unique()

# How many distinct initial velocity values cause the probe to be within the
# target area after any step?
results |>
  dplyr::select(xv, yv) |>
  unique() |>
  nrow()

Day 18: Snailfish

Part 1


path <- here("inst", "2021", "day18.txt")
dat <- read_day18(path)

# Add up all of the snailfish numbers from the homework assignment in the
# order they appear. What is the magnitude of the final sum?
snailfish_maths(dat)

Part 2


# What is the largest magnitude of any sum of two different snailfish numbers
# from the homework assignment?
snailfish_maths2(dat)

Day 19: Beacon Scanner

Part 1


path <- here("inst", "2021", "day19.txt")
scans <- read_day19(path)

# How many beacons are there?
tmp <- assemble_map(scans)
scans <- tmp$scans
scans[[1]] |>
    unique() |>
    nrow()

Part 2


# What is the largest Manhattan distance between any two scanners?
scanners <- tmp$scanners
dist_scanners(scanners)

Day 20: Trench Map

Part 1


# Start with the original input image and apply the image enhancement
# algorithm twice, being careful to account for the infinite size of the
# images
path <- here("inst", "2021", "day20.txt")

input <- get_input(path)
algorithm <- get_algorithm(path)

img <- enhance_image(input, 2, algorithm)
view_image(img)

# How many pixels are lit in the resulting image?
sum(img == "#")

Part 2

# Start again with the original input image and apply the image enhancement algorithm 50 times
img <- enhance_image(input, 50, algorithm)

# How many pixels are lit in the resulting image?
sum(img == "#")

Day 21: Dirac Dice

Part 1


# Play a practice game using the deterministic 100-sided die
path <- here("inst", "2021", "day21.txt")
dat <- read_day21(path)

# The moment either player wins, what do you get if you multiply the score of
# the losing player by the number of times the die was rolled during the game?
deterministic(dat)

Day 22: Reactor Reboot

Part 1


# Read in data
test <- here("inst", "2021", "day22-test.txt")
path <- here("inst", "2021", "day22.txt")

test_dat <- readLines(test) |> read_day22(50)
dat <- readLines(path) |> read_day22(50)

# Execute the reboot steps
assertthat::assert_that(reboot(test_dat) == 590784)
# Considering only cubes in the region x=-50..50,y=-50..50,z=-50..50, how many
# cubes are on?
reboot(dat)

Day 23: Amphipod

Day 24: Arithmetic Logic Unit

Day 25: Sea Cucumber

Part 1


# Read in data
path <- here("inst", "2021", "day25.txt")
dat <- read_day25(path)
cucumbers <- get_cucumbers(dat)

# What is the first step on which no sea cucumbers move?
simulate_cucumbers(dat, cucumbers)

Test data


knitr::include_graphics("recording.gif")


soniamitchell/adventofcode documentation built on Jan. 8, 2022, 9:33 a.m.