Day 9

Advent of Code: Worked Solutions

About
Date

December 9, 2020

Setup

Import libraries:

library(tidyverse)

Read text input from file into a numeric vector:

input <- scan("../input/day09.txt")

Define the preamble length parameter:

preamble <- 25

Part 1

Find the first number in the list (after the preamble) which is not the sum of two of the 25 numbers before it:

invalid_num <- imap(
  tail(input, n = -preamble),
  ~ input[1:preamble - 1 + .y] |> 
    combn(2, simplify = FALSE) |> 
    map_dbl(sum) |> 
    setdiff(x = .x, y = _)
) |> 
  compact() |> 
  pluck(1)

Part 2

Define a function that starts at the first index and examines all following subsequences until their sum either equals or exceeds the invalid number. If it’s found, then return the sum of the minimum and maximum index in that range. If it overshoots, start over from the second index (and so on):

find_weakness <- function(vec, target) {
  idx_start <- 1
  
  while (idx_start < length(vec)) {
    idx_end <- idx_start + 1
    
    while (idx_end <= length(vec)) {
      range <- vec[idx_start:idx_end]
      
      if (sum(range) == target)
        return(min(range) + max(range))
      if (sum(range) > target)
        break
      
      idx_end <- idx_end + 1
    }
    idx_start <- idx_start + 1
  }
}

Run on puzzle input:

find_weakness(input, invalid_num)