Day 13

Advent of Code: Worked Solutions

About
Date

December 13, 2023

Setup

# Libraries
library(tidyverse)

# Read input from file
input <- read_lines("../input/day13.txt", skip_empty_rows = FALSE)

Part 1

Convert each set of input strings into its own matrix:

mtx <- tibble(chr = input) |> 
  group_split(cumsum(chr == "")) |> 
  map(~ pull(.x, chr)) |> 
  map(
    ~ str_split(.x, "") |> 
      unlist() |> 
      matrix(nrow = sum(.x != ""), byrow = TRUE)
  )

Define a function that checks for a mirror along the given dimension (rows vs columns) of a given matrix:

mirror_idx <- function(mtx, dim = c("row", "col")) {
  vecs <- split(mtx, get(case_match(dim, "row" ~ "col", "col" ~ "row"))(mtx))
  len  <- get(str_c("n", dim))(mtx)
  
  refl_idx <- c(0)
  
  for (idx in 1:(len - 1)) {
    n_trim <- min(idx, len - idx)
    
    is_mirror <- vecs |> 
      map_lgl(\(vec) {
        h1 <- rev(vec[1:idx])[1:n_trim]
        h2 <- vec[(idx + 1):(idx + n_trim)]
        all(h1 == h2)
      }) |> 
      all()
    
    if (is_mirror) 
      refl_idx <- c(refl_idx, idx)
  }
  
  refl_idx
}

For each matrix in the list, add the column indices of each vertical reflection line with 100 times the row indices of each horizontal reflection line:

score_matrices <- function(mtx_list) {
  mtx_list |> 
    map_dbl(~ sum(mirror_idx(.x, "col")) + sum(mirror_idx(.x, "row") * 100)) |> 
    sum()
}

score_matrices(mtx)
[1] 30575

Part 2

Define a function that finds the row or column index of the single smudge for a given matrix:

smudge_idx <- function(mtx, dim = c("row", "col")) {
  
  vecs <- split(mtx, get(case_match(dim, "row" ~ "col", "col" ~ "row"))(mtx))
  len  <- get(str_c("n", dim))(mtx)
  
  for (idx in 1:(len - 1)) {
    n_trim <- min(idx, len - idx)
    
    noteq <- vecs |> 
      map(\(vec) {
        h1 <- rev(vec[1:idx])[1:n_trim]
        h2 <- vec[(idx + 1):(idx + n_trim)]
        which(h1 != h2)
      })
    
    if (length(unlist(noteq)) == 1) return(idx)
  }
  return(0)
}

Re-score the input:

score_unsmudged <- function(mtx_list) {
  mtx_list |> 
    map_dbl(~ sum(smudge_idx(.x, "col")) + sum(smudge_idx(.x, "row") * 100)) |> 
    sum()
}

score_unsmudged(mtx)
[1] 37478