Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/dgrtwo/adventdrob

Personal R package for Advent of Code
https://github.com/dgrtwo/adventdrob

Last synced: about 2 months ago
JSON representation

Personal R package for Advent of Code

Awesome Lists containing this project

README

        

```{r, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
fig.path = "man/figures/README-",
out.width = "100%"
)
```

# DRob's Advent of Code functions

Personal R package meant to help me compete in [Advent of Code](https://adventofcode.com/), especially functions for working with data formats common in the puzzles such as grids. This includes:

* An `advent_input` function that reads in a one-column tibble
* Functions for parsing grids (helpful on days 3, 4, 9, and 11 of 2021)

Feel free to use it yourself! Note I don't intend to maintain or support it, but I might add to it as 2021's Advent goes along and I find other patterns that pop up multiple times.

## Installation

You can install the development version of adventdrob like so:

``` r
devtools::install_github("dgrtwo/adventdrob")
```

You'll then have to set ADVENT_SESSION in your .Renviron to your Advent of Code cookie. Example of how to get that in Chrome:

* Visit [adventofcode.com](https://adventofcode.com/), and log in
* Right click + Inspect to view Developer Tools
* Select the Network tab
* Refresh the page, and select the "adventofcode.com" request
* Under Request Headers, there should be a cookie including `session=`. Copy that without the session=.

## Example: 2021 Day 9

[Day 9 of the 2021 puzzle](https://adventofcode.com/2021/day/9) provides a grid of digits. `advent_input()` reads this into a one-column tibble.

```{r example}
library(dplyr)
library(adventdrob)

input <- advent_input(9, 2021)
input
```

### Part 1

Part 1 tasks us to find the points that are lower than any adjacent point. Excerpts from the puzzle follow.

> Your first goal is to find the low points - the locations that are lower than any of its adjacent locations... (Diagonal locations do not count as adjacent.)

> The risk level of a low point is 1 plus its height.

> Find all of the low points on your heightmap. What is the sum of the risk levels of all low points on your heightmap?

The input can be parsed with `grid_tidy` to create a tidy one-row-per-cell form of row, column and value.

```{r}
input %>%
grid_tidy(x)
```

We can use `adjacent_join` to join each `row/col` pair with the adjacent `row2/col2` pair.

```{r}
input %>%
grid_tidy(x) %>%
adjacent_join()
```

With a bit of summarizing, we can find all points that are greater than all their neighbors.

```{r}
input %>%
grid_tidy(x) %>%
adjacent_join() %>%
group_by(row, col, value) %>%
summarize(low = all(value2 > value), .groups = "drop") %>%
filter(low) %>%
summarize(sum(value + 1))
```

### Part 2

For some problems, the best form isn't a tidy table, but a [tidygraph](https://github.com/thomasp85/tidygraph) object.

> A basin is all locations that eventually flow downward to a single low point. Therefore, every low point has a basin, although some basins are very small. Locations of height 9 do not count as being in any basin, and all other locations will always be part of exactly one basin.

> The size of a basin is the number of locations within the basin, including the low point.

> What do you get if you multiply together the sizes of the three largest basins?

This is well suited to finding connected components within a graph. (Many thanks to Jarosław Nirski on the [R for Data Science Slack](https://rfordatascience.slack.com/) for this approach!)

```{r}
input %>%
grid_graph(x)
```

As it happens, this lets us answer part 2 in a few lines, thanks to the `group_components()` function in tidygraph.

```{r}
advent_input(9) %>%
grid_graph(x) %>%
filter(value != 9) %>%
mutate(component = tidygraph::group_components()) %>%
as_tibble() %>%
count(component, sort = TRUE) %>%
head(3) %>%
summarize(answer = prod(n))
```