Skip to content

Commit 6feec12

Browse files
committed
2022 Day 23
1 parent 3f30c77 commit 6feec12

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+1858
-319
lines changed

2022/R/day23.qmd

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
---
2+
title: "Day 23"
3+
date: 2022-12-23
4+
author:
5+
name: https://adventofcode.com/2022/day/23
6+
url: https://adventofcode.com/2022/day/23
7+
---
8+
9+
## Setup
10+
11+
```{r setup}
12+
13+
# Libraries
14+
library(tidyverse)
15+
16+
# Read input from file
17+
input <- read_lines("../input/day23.txt", skip_empty_rows = TRUE) |>
18+
enframe(name = "row") |>
19+
mutate(value = map(value, ~ enframe(str_split_1(.x, ""), name = "col"))) |>
20+
unnest(value)
21+
22+
```
23+
24+
## Part 1
25+
26+
Convert map to a list of positions for each elf, using complex numbers to store 2D coords:
27+
28+
```{r}
29+
30+
elves <- input |>
31+
filter(value == "#") |>
32+
mutate(z = complex(real = col, imaginary = row)) |>
33+
pull(z)
34+
35+
```
36+
37+
Define function to move elves in each round:
38+
39+
```{r}
40+
41+
cardinal_dirs <- c(
42+
n = 0 - 1i,
43+
s = 0 + 1i,
44+
w = -1 + 0i,
45+
e = 1 + 0i,
46+
nw = -1 - 1i,
47+
ne = 1 - 1i,
48+
sw = -1 + 1i,
49+
se = 1 + 1i
50+
)
51+
52+
adjacent_dirs <- list(
53+
n = c("n", "nw", "ne"),
54+
s = c("s", "sw", "se"),
55+
w = c("w", "nw", "sw"),
56+
e = c("e", "ne", "se")
57+
)
58+
59+
move_elves <- function(elves, round_num) {
60+
61+
# Determine which neighboring cells are occupied
62+
neighbors <- map(cardinal_dirs, \(dir) elves + dir)
63+
occupied <- map(neighbors, ~ .x %in% elves)
64+
65+
# Determine which n/s/w/e moves are valid
66+
valid <- map(adjacent_dirs, \(dir_set) {
67+
dir_set |>
68+
map(~!occupied[[.x]]) |>
69+
reduce(`&`)
70+
})
71+
72+
# Re-order the n/s/w/e priority according to the current round number
73+
valid <- valid[(1:4 + round_num - 2) %% 4 + 1]
74+
75+
# For all elves not surrounded by empty cells, determine their proposed move
76+
all_borders_empty <- reduce(valid, `&`)
77+
proposals <- valid |>
78+
imap(\(vec, dir) case_when(vec ~ neighbors[[dir]])) |>
79+
pmap(
80+
~ c(discard(c(..1, ..2, ..3, ..4), is.na), NA) |>
81+
head(1)
82+
) |>
83+
unlist() |>
84+
modify_if(all_borders_empty, ~ NA)
85+
86+
# Nullify any colliding proposed moves
87+
collisions <- na.omit(proposals)[duplicated(na.omit(proposals))]
88+
movements <- if_else(proposals %in% collisions, NA, proposals)
89+
90+
# Return the new elf coordinates
91+
coalesce(movements, elves)
92+
}
93+
94+
```
95+
96+
Define a function to compute the area of the bounding box then subtract away the number of elves:
97+
98+
```{r}
99+
100+
n_empty_tiles <- function(elves) {
101+
height <- 1 + diff(range(Im(elves)))
102+
width <- 1 + diff(range(Re(elves)))
103+
104+
height * width - length(elves)
105+
}
106+
107+
```
108+
109+
Run 10 rounds on puzzle input:
110+
111+
```{r}
112+
113+
reduce(1:10, move_elves, .init = elves) |>
114+
n_empty_tiles()
115+
116+
```
117+
118+
## Part 2
119+
120+
Run until no further movements occur:
121+
122+
```{r}
123+
124+
i <- 1
125+
cur_elves <- elves
126+
127+
repeat {
128+
new_elves <- move_elves(cur_elves, i)
129+
130+
if (all(new_elves == cur_elves)) break
131+
132+
cur_elves <- new_elves
133+
i <- i + 1
134+
}
135+
136+
i
137+
138+
```
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"hash": "55a4440ee28c9580f6107d1afd9797f2",
3+
"result": {
4+
"engine": "knitr",
5+
"markdown": "---\ntitle: \"Day 23\"\ndate: 2022-12-23\nauthor:\n name: https://adventofcode.com/2022/day/23\n url: https://adventofcode.com/2022/day/23\n---\n\n\n\n\n## Setup\n\n\n\n\n::: {.cell}\n\n```{.r .cell-code}\n# Libraries\nlibrary(tidyverse)\n\n# Read input from file\ninput <- read_lines(\"../input/day23.txt\", skip_empty_rows = TRUE) |> \n enframe(name = \"row\") |> \n mutate(value = map(value, ~ enframe(str_split_1(.x, \"\"), name = \"col\"))) |> \n unnest(value)\n```\n:::\n\n\n\n\n## Part 1\n\nConvert map to a list of positions for each elf, using complex numbers to store 2D coords:\n\n\n\n\n::: {.cell}\n\n```{.r .cell-code}\nelves <- input |> \n filter(value == \"#\") |> \n mutate(z = complex(real = col, imaginary = row)) |> \n pull(z)\n```\n:::\n\n\n\n\nDefine function to move elves in each round:\n\n\n\n\n::: {.cell}\n\n```{.r .cell-code}\ncardinal_dirs <- c(\n n = 0 - 1i,\n s = 0 + 1i,\n w = -1 + 0i,\n e = 1 + 0i,\n nw = -1 - 1i,\n ne = 1 - 1i,\n sw = -1 + 1i,\n se = 1 + 1i\n)\n\nadjacent_dirs <- list(\n n = c(\"n\", \"nw\", \"ne\"),\n s = c(\"s\", \"sw\", \"se\"),\n w = c(\"w\", \"nw\", \"sw\"),\n e = c(\"e\", \"ne\", \"se\")\n)\n\nmove_elves <- function(elves, round_num) {\n\n # Determine which neighboring cells are occupied\n neighbors <- map(cardinal_dirs, \\(dir) elves + dir)\n occupied <- map(neighbors, ~ .x %in% elves)\n \n # Determine which n/s/w/e moves are valid\n valid <- map(adjacent_dirs, \\(dir_set) {\n dir_set |> \n map(~!occupied[[.x]]) |> \n reduce(`&`)\n })\n \n # Re-order the n/s/w/e priority according to the current round number\n valid <- valid[(1:4 + round_num - 2) %% 4 + 1]\n \n # For all elves not surrounded by empty cells, determine their proposed move\n all_borders_empty <- reduce(valid, `&`)\n proposals <- valid |> \n imap(\\(vec, dir) case_when(vec ~ neighbors[[dir]])) |>\n pmap(\n ~ c(discard(c(..1, ..2, ..3, ..4), is.na), NA) |> \n head(1)\n ) |> \n unlist() |> \n modify_if(all_borders_empty, ~ NA)\n \n # Nullify any colliding proposed moves\n collisions <- na.omit(proposals)[duplicated(na.omit(proposals))]\n movements <- if_else(proposals %in% collisions, NA, proposals)\n \n # Return the new elf coordinates\n coalesce(movements, elves)\n}\n```\n:::\n\n\n\n\nDefine a function to compute the area of the bounding box then subtract away the number of elves:\n\n\n\n\n::: {.cell}\n\n```{.r .cell-code}\nn_empty_tiles <- function(elves) {\n height <- 1 + diff(range(Im(elves)))\n width <- 1 + diff(range(Re(elves)))\n \n height * width - length(elves)\n}\n```\n:::\n\n\n\n\nRun 10 rounds on puzzle input:\n\n\n\n\n::: {.cell}\n\n```{.r .cell-code}\nreduce(1:10, move_elves, .init = elves) |> \n n_empty_tiles()\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n[1] 3996\n```\n\n\n:::\n:::\n\n\n\n\n## Part 2\n\nRun until no further movements occur:\n\n\n\n\n::: {.cell}\n\n```{.r .cell-code}\ni <- 1\ncur_elves <- elves\n\nrepeat {\n new_elves <- move_elves(cur_elves, i)\n \n if (all(new_elves == cur_elves)) break\n \n cur_elves <- new_elves\n i <- i + 1\n}\n\ni\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n[1] 908\n```\n\n\n:::\n:::\n",
6+
"supporting": [],
7+
"filters": [
8+
"rmarkdown/pagebreak.lua"
9+
],
10+
"includes": {},
11+
"engineDependencies": {},
12+
"preserve": {},
13+
"postProcess": true
14+
}
15+
}

docs/2022/R/day01.html

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,12 @@ <h1 class="quarto-secondary-nav-title">Day 1</h1>
436436
<a href="../../2022/R/day22.html" class="sidebar-item-text sidebar-link">
437437
<span class="menu-text">Day 22</span></a>
438438
</div>
439+
</li>
440+
<li class="sidebar-item">
441+
<div class="sidebar-item-container">
442+
<a href="../../2022/R/day23.html" class="sidebar-item-text sidebar-link">
443+
<span class="menu-text">Day 23</span></a>
444+
</div>
439445
</li>
440446
</ul>
441447
</li>

docs/2022/R/day02.html

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,12 @@ <h1 class="quarto-secondary-nav-title">Day 2</h1>
436436
<a href="../../2022/R/day22.html" class="sidebar-item-text sidebar-link">
437437
<span class="menu-text">Day 22</span></a>
438438
</div>
439+
</li>
440+
<li class="sidebar-item">
441+
<div class="sidebar-item-container">
442+
<a href="../../2022/R/day23.html" class="sidebar-item-text sidebar-link">
443+
<span class="menu-text">Day 23</span></a>
444+
</div>
439445
</li>
440446
</ul>
441447
</li>

docs/2022/R/day03.html

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,12 @@ <h1 class="quarto-secondary-nav-title">Day 3</h1>
436436
<a href="../../2022/R/day22.html" class="sidebar-item-text sidebar-link">
437437
<span class="menu-text">Day 22</span></a>
438438
</div>
439+
</li>
440+
<li class="sidebar-item">
441+
<div class="sidebar-item-container">
442+
<a href="../../2022/R/day23.html" class="sidebar-item-text sidebar-link">
443+
<span class="menu-text">Day 23</span></a>
444+
</div>
439445
</li>
440446
</ul>
441447
</li>

docs/2022/R/day04.html

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,12 @@ <h1 class="quarto-secondary-nav-title">Day 4</h1>
436436
<a href="../../2022/R/day22.html" class="sidebar-item-text sidebar-link">
437437
<span class="menu-text">Day 22</span></a>
438438
</div>
439+
</li>
440+
<li class="sidebar-item">
441+
<div class="sidebar-item-container">
442+
<a href="../../2022/R/day23.html" class="sidebar-item-text sidebar-link">
443+
<span class="menu-text">Day 23</span></a>
444+
</div>
439445
</li>
440446
</ul>
441447
</li>

docs/2022/R/day05.html

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,12 @@ <h1 class="quarto-secondary-nav-title">Day 5</h1>
436436
<a href="../../2022/R/day22.html" class="sidebar-item-text sidebar-link">
437437
<span class="menu-text">Day 22</span></a>
438438
</div>
439+
</li>
440+
<li class="sidebar-item">
441+
<div class="sidebar-item-container">
442+
<a href="../../2022/R/day23.html" class="sidebar-item-text sidebar-link">
443+
<span class="menu-text">Day 23</span></a>
444+
</div>
439445
</li>
440446
</ul>
441447
</li>

docs/2022/R/day06.html

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,12 @@ <h1 class="quarto-secondary-nav-title">Day 6</h1>
436436
<a href="../../2022/R/day22.html" class="sidebar-item-text sidebar-link">
437437
<span class="menu-text">Day 22</span></a>
438438
</div>
439+
</li>
440+
<li class="sidebar-item">
441+
<div class="sidebar-item-container">
442+
<a href="../../2022/R/day23.html" class="sidebar-item-text sidebar-link">
443+
<span class="menu-text">Day 23</span></a>
444+
</div>
439445
</li>
440446
</ul>
441447
</li>

docs/2022/R/day07.html

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,12 @@ <h1 class="quarto-secondary-nav-title">Day 7</h1>
436436
<a href="../../2022/R/day22.html" class="sidebar-item-text sidebar-link">
437437
<span class="menu-text">Day 22</span></a>
438438
</div>
439+
</li>
440+
<li class="sidebar-item">
441+
<div class="sidebar-item-container">
442+
<a href="../../2022/R/day23.html" class="sidebar-item-text sidebar-link">
443+
<span class="menu-text">Day 23</span></a>
444+
</div>
439445
</li>
440446
</ul>
441447
</li>

docs/2022/R/day08.html

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,12 @@ <h1 class="quarto-secondary-nav-title">Day 8</h1>
436436
<a href="../../2022/R/day22.html" class="sidebar-item-text sidebar-link">
437437
<span class="menu-text">Day 22</span></a>
438438
</div>
439+
</li>
440+
<li class="sidebar-item">
441+
<div class="sidebar-item-container">
442+
<a href="../../2022/R/day23.html" class="sidebar-item-text sidebar-link">
443+
<span class="menu-text">Day 23</span></a>
444+
</div>
439445
</li>
440446
</ul>
441447
</li>

0 commit comments

Comments
 (0)