Day 7

Advent of Code: Worked Solutions

About
Date

December 7, 2024

Setup

Import libraries:

library(tidyverse)
library(unglue)

Disable scientific formatting when displaying large numbers:

options(scipen = 999)

Read plaintext input from file into a dataframe of target / numeric sequence pairs:

input <- read_lines("../input/day07.txt") |> 
  unglue_data("{target}: {seq}", convert = TRUE) |> 
  mutate(seq = map(seq, ~ as.numeric(str_split_1(.x, " "))))

Part 1

Define a recursive function that explores every combination of operators for a given seq and returns when any path to the target output is found:

calibrate <- function(seq, target, operators) {
  
  # If the end of the list has been reached, check if we hit the target & exit
  if (length(seq) == 1) 
    return(seq == target)
  
  # If the target is already overshot, exit
  if (seq[1] > target)
    return(FALSE)
  
  # Collapse the first two items in the seq for each operator & recurse
  map_lgl(operators, \(f) {
    new_start <- get(f)(seq[1], seq[2])
    new_seq <- c(new_start, tail(seq, -2))
    calibrate_operators(new_seq, target, operators)
  }) |> 
    # If any output is true, the output has been calibrated.
    any()
}

Loop through every seq-target pair to determine which are valid, then sum their outputs:

input |> 
  filter(map2_lgl(seq, target, ~ calibrate(.x, .y, c("+", "*")))) |> 
  pull(target) |> 
  sum()

Part 2

Define a new concatenation operator:

concat <- \(x, y) as.numeric(str_c(x, y))

Re-run the calibration on the puzzle input with the new concat operator:

input |> 
  filter(map2_lgl(seq, target, ~ calibrate(.x, .y, c("+", "*", "concat")))) |> 
  pull(target) |> 
  sum()