‘Tilt’ a matrix to roll the "O"s until they reach a "#".

Toggle the code

# reverse order of rowsinput_rev <- input[nrow(input):1, ]# function to tilt one column and find the loadtilt <-function(col) { sorted <- col |>factor(levels =c("#", ".", "O")) |>split(cumsum(col =="#")) |>lapply(sort) |>do.call(c, args = _) which(sorted =="O") |>sum()}# apply to all columns and find total loadapply(input_rev, 2, tilt) |>sum()

[1] 105461

The puzzle talks about tilting north, but since the load is equal to the number of rows from the bottom, in terms of associating the load with the row index, it’s easier to reverse the order of the rows and think about tilting the matrix south.

Next, a function that will order one column. The strategy is to split the column at the "#"s, sort each element of the resulting list to move the "O"s (having converted the vector into a factor so we can sort in the desired order),
then rejoin the vector. We can then find the indices of the round rocks, and their sum is the load for that column.

Finally, apply that to each column of the matrix, and find the total sum.

Part 2

The crux of the puzzle

Something to do with cycles.

This doesn’t seem well-suited to a brute force approach. At the time of writing, I’m not familiar with any algorithm that would be suitable here. On the R4DS Slack, Jonathan Carroll and Tan Ho have hinted about using the cycle-detection algorithm and have posted their solutions. At some point, I may come back to this, read about the algorithm and either attempt to implement it myself, or work through their code to get a deeper understanding.

Session info

Toggle

─ Session info ───────────────────────────────────────────────────────────────
setting value
version R version 4.3.2 (2023-10-31)
os macOS Sonoma 14.1
system aarch64, darwin20
ui X11
language (EN)
collate en_US.UTF-8
ctype en_US.UTF-8
tz Europe/London
date 2023-12-15
pandoc 3.1.1 @ /Applications/RStudio.app/Contents/Resources/app/quarto/bin/tools/ (via rmarkdown)
quarto 1.4.526 @ /usr/local/bin/quarto
─ Packages ───────────────────────────────────────────────────────────────────
package * version date (UTC) lib source
aochelpers * 0.1.0.9000 2023-12-06 [1] local
sessioninfo * 1.2.2 2021-12-06 [1] CRAN (R 4.3.0)
[1] /Users/ellakaye/Library/R/arm64/4.3/library
[2] /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/library
──────────────────────────────────────────────────────────────────────────────

Source Code

---title: "2023: Day 14"date: 2023-12-14author: - name: Ella Kayecategories: [base R, matrices, ⭐]draft: false---## Setup[The original challenge](https://adventofcode.com/2023/day/14)[My data](input){target="_blank"}## Part 1```{r}#| echo: falseOK <-"2023"<3000# Will only evaluate next code block if an actual year has been substituted for the placeholder.``````{r}#| eval: !expr OKlibrary(aochelpers)input <-aoc_input_matrix(14, 2023)head(input, c(6, 6))```::: {.callout-note collapse="false" icon="false"}## The crux of the puzzle'Tilt' a matrix to roll the `"O"`s until they reach a `"#"`.:::```{r}# reverse order of rowsinput_rev <- input[nrow(input):1, ]# function to tilt one column and find the loadtilt <-function(col) { sorted <- col |>factor(levels =c("#", ".", "O")) |>split(cumsum(col =="#")) |>lapply(sort) |>do.call(c, args = _) which(sorted =="O") |>sum()}# apply to all columns and find total loadapply(input_rev, 2, tilt) |>sum() ```The puzzle talks about tilting north, but since the load is equal to the number of rows from the bottom,in terms of associating the load with the row index, it's easier to reverse the order of the rows and think about tilting the matrix south.Next, a function that will order one column.The strategy is to split the column at the `"#"`s,sort each element of the resulting list to move the `"O"`s (having converted the vector into a factor so we can sort in the desired order), then rejoin the vector. We can then find the indices of the round rocks, and their sum is the load for that column.Finally, apply that to each column of the matrix,and find the total sum.## Part 2::: {.callout-note collapse="false" icon="false"}## The crux of the puzzleSomething to do with cycles.:::This doesn't seem well-suited to a brute force approach.At the time of writing, I'm not familiar with any algorithm that would be suitable here. On the R4DS Slack, Jonathan Carroll and Tan Ho have hinted about using the cycle-detection algorithm and have posted their solutions.At some point, I may come back to this, read about the algorithm and either attempt to implement it myself, or work through their code to get a deeper understanding.##### Session info {.appendix}<details><summary>Toggle</summary>```{r}#| echo: falselibrary(sessioninfo)# save the session info as an objectpkg_session <-session_info(pkgs ="attached")# get the quarto versionquarto_version <-system("quarto --version", intern =TRUE)# inject the quarto infopkg_session$platform$quarto <-paste(system("quarto --version", intern =TRUE), "@", quarto::quarto_path() )# print it outpkg_session```</details>