library(tidyverse)
library(here)
Part 1
Part 1 of this puzzle is fairly straight forward. The goal of Part 1 is to identify the next number in the ‘history’. In order to identify the next value in the history, we need to identify the difference between the values, until the differences in the values is 0. We would then sum the last value of all the differences in order to obtain the next value in the history.
The puzzle prompt is as follows:
Analyze your OASIS report and extrapolate the next value for each history. What is the sum of these extrapolated values?
We would then take the sum of the predicted next history among all of the histories.
Let’s start off with reading in the puzzle input.
<- read_lines(
data here('posts', 'aoc-2023-d9', 'puzzle-input.txt')
)
|> head() data
[1] "12 12 11 5 -5 -5 40 194 558 1278 2553 4643 7877 12661 19486 28936 41696 58560 80439 108369 143519"
[2] "6 12 33 79 163 320 638 1301 2644 5220 9879 17859 30889 51304 82172 127433 192050 282172 405309 570519 788607"
[3] "3 5 5 3 9 60 262 872 2445 6091 13915 29744 60271 116756 217404 390473 678031 1140057 1858241 2938353 4509389"
[4] "15 21 23 31 67 161 350 681 1224 2114 3674 6758 13659 30354 71646 172084 407585 935627 2065861 4378033 8910071"
[5] "13 32 75 155 286 477 724 1011 1347 1894 3301 7501 19549 51737 132449 324337 759840 1707391 3689542 7685418 15464987"
[6] "9 23 59 129 245 419 663 989 1409 1935 2579 3353 4269 5339 6575 7989 9593 11399 13419 15665 18149"
Now let’s clean up the data a bit, we’ll start by splitting the history by spaces and converting the history into a column of a tibble.
<- map(data, \(x) {
data |>
x str_split(' ') |>
unlist() |>
as_tibble() |>
mutate(value = as.numeric(value)) |>
rename('c0' = value)
})
|> head() data
[[1]]
# A tibble: 21 × 1
c0
<dbl>
1 12
2 12
3 11
4 5
5 -5
6 -5
7 40
8 194
9 558
10 1278
# ℹ 11 more rows
[[2]]
# A tibble: 21 × 1
c0
<dbl>
1 6
2 12
3 33
4 79
5 163
6 320
7 638
8 1301
9 2644
10 5220
# ℹ 11 more rows
[[3]]
# A tibble: 21 × 1
c0
<dbl>
1 3
2 5
3 5
4 3
5 9
6 60
7 262
8 872
9 2445
10 6091
# ℹ 11 more rows
[[4]]
# A tibble: 21 × 1
c0
<dbl>
1 15
2 21
3 23
4 31
5 67
6 161
7 350
8 681
9 1224
10 2114
# ℹ 11 more rows
[[5]]
# A tibble: 21 × 1
c0
<dbl>
1 13
2 32
3 75
4 155
5 286
6 477
7 724
8 1011
9 1347
10 1894
# ℹ 11 more rows
[[6]]
# A tibble: 21 × 1
c0
<dbl>
1 9
2 23
3 59
4 129
5 245
6 419
7 663
8 989
9 1409
10 1935
# ℹ 11 more rows
I’m going to create two helper functions to facilitate this puzzle, first it’s generate_new_columns
. This function will create new columns with the differences based on the previous column. The second function predicted_next_history
will continue to calculate the differences in new columns until all the values are zero.
<- \(data, new_column, prev_column) {
generate_new_columns <- rlang::parse_expr(prev_column)
prev_column <- rlang::parse_expr(new_column)
new_column
<- data |>
temp mutate(!!new_column := !!prev_column - lag(!!prev_column)) |>
select(!!new_column)
bind_cols(data, temp)
}
<- \(history) {
predicted_next_history
<- FALSE
all_zeroes <- 0
i <- history
temp <- NULL
prev
while (all_zeroes == FALSE) {
<- paste0('c', i + 1)
new <- paste0('c', i)
prev
<- generate_new_columns(temp, new, prev)
temp <- temp |> pull(!!new) |> na.omit()
new_column <- all(new_column == 0)
all_zeroes
<- i + 1
i
}
<- map(temp, \(x) {
values <- x |> na.omit()
vals
<- length(vals)
total_vals
return(vals[total_vals])
})
|> unlist() |> sum()
values
}
Now we can apply these helper functions to all of the histories.
<-
results map(data, \(x) predicted_next_history(x), .progress = 'Predicting Next History:')
|> head() results
[[1]]
[1] 187199
[[2]]
[1] 1072336
[[3]]
[1] 6716828
[[4]]
[1] 17445671
[[5]]
[1] 30121668
[[6]]
[1] 20883
One we have all of the predicted next hsitories, we can take the sum to get the answer.
|> unlist() |> sum() results
Part 2
Part 2 of the puzzle is fairly simple, instead of the next value in the history we need to identify the previous value of the history. We simply modify the code to the predicted_next_history
function to identify the reverse.
<- \(history) {
predicted_prev_history
<- FALSE
all_zeroes <- 0
i <- history
temp <- NULL
prev
while (all_zeroes == FALSE) {
<- paste0('c', i + 1)
new <- paste0('c', i)
prev
<- generate_new_columns(temp, new, prev)
temp <- temp |> pull(!!new) |> na.omit()
new_column <- all(new_column == 0)
all_zeroes
<- i + 1
i
}
<- map(temp, \(x) {
values <- x |> na.omit()
vals
return(vals[1])
})
<- values |>
values unlist()
<- values[1:length(values) - 1]
values
<- rev(values)
values
<- 0
current_value <- map(values, \(x) {
values <<- x - current_value
current_value
|> unlist()
})
length(values)] |> unname()
values[
}
<-
results map(data, \(x) predicted_prev_history(x), .progress = 'Predicting Prev History:')
|> head() results
[[1]]
[1] 12
[[2]]
[1] 1
[[3]]
[1] 3
[[4]]
[1] 10
[[5]]
[1] 8
[[6]]
[1] 5
With the results, we can take the sum to get the answer.
|> unlist() |> sum() results
Reuse
Citation
@online{luu2023,
author = {Luu, Michael},
title = {Advent of {Code} 2023, {Day} 9},
date = {2023-12-10},
langid = {en}
}