# Libraries
library(tidyverse)
# Read input from file
<- read_lines("../input/day09.txt", skip_empty_rows = TRUE) |>
input str_split_1("") |>
as.integer()
Day 9
Advent of Code: Worked Solutions
Setup
Part 1
Define custom file functions:
<- function(filesys) {
move_files repeat {
<- min(which(is.na(filesys)))
first_blank <- max(which(!is.na(filesys)))
last_file
# If all files have been compressed, exit
if (first_blank > last_file) break
# Otherwise, move the last file into the first blank location
<- filesys[last_file]
filesys[first_blank] <- NA_integer_
filesys[last_file]
}
filesys
}
<- function(filesys) {
checksum |>
filesys imap_int(\(x, idx) if_else(is.na(x), 0, x * (idx - 1))) |>
sum() |>
format(scientific = FALSE)
}
Run puzzle input:
# Uncompress file layout
<- input|>
filesys imap(function(x, idx) {
# Even entries are files; odd entries are spaces
<- if_else(idx %% 2 == 1, floor(idx / 2), NA_integer_)
file_id rep(file_id, x)
|>
}) unlist()
|>
filesys move_files() |>
checksum()
[1] "6330095022244"
Part 2
Update the compression function:
<- function(filesys) {
move_blocks for (file_id in max(na.omit(filesys)):1) {
# Pull the location and length of the file block for the current ID
<- which(filesys == file_id)
file_block <- length(file_block)
n
# Pull indices of all empty values before the current file block
<- which(is.na(filesys[1:min(file_block)]))
empty_idx
# Pull all valid starting indices of empty blocks of the right length
if (n == 1) {
<- empty_idx
valid_idx else {
} <- replace_na(lead(empty_idx, n - 1) - empty_idx == n - 1, FALSE)
valid_block <- empty_idx[valid_block]
valid_idx
}
# If valid indices exist, move the file block to the first valid location
if (length(valid_idx) > 0) {
<- min(valid_idx)
idx_start :(idx_start + n - 1)] <- file_id
filesys[idx_start<- NA_integer_
filesys[file_block]
}
}
filesys }
Run puzzle input:
|>
filesys move_blocks() |>
checksum()
[1] "6359491814941"