04: Ceres Search
Part 1
I’m disappointed in myself. I really should have a function to parse input like this by now, but again I sat on my butt and didn’t make one then struggled for it. I also got super duper stuck when my mistlecode::get_diagonal()
wasn’t able to pick up diagonals that start in the lower right corner. It’s something I’ll have to go fix. I’ll probably re-do the whole thing to just say ‘top-left’ or ‘bottom-right’ or something to actually say what corner it’s coming off of rather than trying to say how it’s divided. Anyways, I knew I had overlapping diagonals and needed to drop them, but I was dropping them inside count_diag()
which wasn’t doing anything except dropping a letter off the diagonals. Once I moved that outside, I was able to recognize my missing corner.
count <- function(x) {
x |>
paste0(collapse = '') |>
mistlecode::strg_extract_all('XMAS|SAMX') |>
unlist() |>
length()
}
count_diag <- function(x, dim, dir) {
x |>
purrr::map_int(\(x) {
mistlecode::get_diagonal(dt, x, dim, dir) |>
count()
}) |>
sum()
}
rows <- dt |> apply(1, count) |> sum()
cols <- dt |> apply(2, count) |> sum()
drow <- dt |> nrow() |> seq_len() |> count_diag('row', 'down')
dcol <- dt |> ncol() |> seq_len() |> tail(-1) |> count_diag('col', 'down')
urow <-
dt |> rev() |> `dim<-`(rev(dim(dt))) |>
nrow() |> seq_len() |> count_diag('row', 'up')
ucol <-
dt |> rev() |> `dim<-`(rev(dim(dt))) |>
ncol() |> seq_len() |> tail(-1) |> count_diag('col', 'up')
rows + cols + drow + dcol + urow + ucol
[1] 2524
Part 2
Thankfully this was much easier. It was a small struggle adapting my count()
which I really didn’t need to do if I hadn’t been so eager to paste0()
in my for
loop. But if it works, it works, and it was much much faster than part 1.
dt[dt == 'X'] <- ''
count <- function(x) {
x |>
stringr::str_count('MAS|SAM') |>
sum()
}
tally <- logical()
for (r in seq_len(nrow(dt) - 2)) {
for (c in seq_len(ncol(dt) - 2)) {
x <- dt[r:(r+2), c:(c+2)]
if (x[2, 2] != 'A') next
left_right <- paste0(c(x[1,1], x[2,2], x[3,3]), collapse = '')
right_left <- paste0(c(x[1,3], x[2,2], x[3,1]), collapse = '')
valid <- count(c(left_right, right_left)) == 2
if (valid) tally <- c(tally, valid)
}
}
tally |>
sum()
[1] 1873