Skip to content

Commit fd6c906

Browse files
committed
2022 Day 16
1 parent 97d9aaf commit fd6c906

File tree

13 files changed

+884
-27
lines changed

13 files changed

+884
-27
lines changed

2022/R/day16.qmd

Lines changed: 124 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,135 @@ input <- read_lines("../input/day16.txt", skip_empty_rows = TRUE) |>
2727

2828
## Part 1
2929

30+
Represent tunnels and valves as a graph:
31+
3032
```{r}
31-
edges <- input |>
33+
34+
g <- input |>
3235
unnest(target) |>
3336
pmap(function(source, target, ...) c(source, target)) |>
3437
unique() |>
3538
unlist() |>
36-
make_graph(directed = TRUE)
39+
make_graph(directed = TRUE) |>
40+
as_undirected()
41+
42+
```
43+
44+
Get the list of valves with nonzero flow:
45+
46+
```{r}
47+
48+
flows <- input |>
49+
filter(rate > 0 | source == "AA") |>
50+
select(source, rate) |>
51+
deframe()
52+
53+
non_init_flows <- flows |>
54+
discard_at("AA")
55+
56+
valves <- names(flows)
57+
58+
dists <- distances(g, valves, valves)
59+
60+
```
61+
62+
List all permutations of possible valves to visit with a total distance less than 30:
63+
64+
```{r}
65+
66+
get_path <- function(choices, last, cur_length, max_length) {
67+
if (cur_length >= max_length)
68+
return(head(last, -1))
69+
if (length(choices) == 0)
70+
return(last)
71+
72+
ls <- list()
73+
for (valve in choices) {
74+
ls <- append(
75+
ls,
76+
list(get_path(
77+
choices[choices != valve],
78+
c(last, valve),
79+
cur_length + dists[tail(last, 1), valve] + 1,
80+
max_length
81+
))
82+
)
83+
}
84+
ls |>
85+
discard(is_null) |>
86+
list_flatten() |>
87+
unique()
88+
}
89+
90+
combos <- get_path(names(non_init_flows), names(flows["AA"]), 0, 30)
91+
92+
```
93+
94+
Compute total pressure released for each permutation:
95+
96+
```{r}
97+
98+
get_pressures <- function(paths, max_time) {
99+
map_dbl(paths, \(path) {
100+
valve <- tail(path, -1)
101+
valve_lag <- head(path, -1)
102+
flow <- tail(flows[path], -1)
103+
104+
dist <- map2_int(valve_lag, valve, \(src, target) dists[src, target])
105+
time_start <- cumsum(dist) + 1:length(dist) + 1
106+
pressure <- (max_time - time_start + 1) * flow
107+
108+
sum(pressure[time_start <= max_time])
109+
})
110+
}
111+
112+
pressures <- get_pressures(combos, 30)
113+
114+
```
115+
116+
Find the permutation that gives the maximum pressure:
117+
118+
```{r}
119+
120+
max_idx <- which.max(pressures)
121+
pressures[max_idx]
122+
123+
```
124+
125+
## Part 2
126+
127+
List all permutations of possible valves to visit with a total distance less than 26:
128+
129+
```{r}
130+
131+
el_combos <- get_path(names(non_init_flows), names(flows["AA"]), 0, 26)
132+
el_pressures <- get_pressures(el_combos, 26)
133+
134+
```
135+
136+
For each set of permutations, get the best pressure.
137+
138+
```{r}
139+
140+
el_best <- tibble(valves = map(el_combos, sort), pressure = el_pressures) |>
141+
slice_max(pressure, by = valves, with_ties = FALSE)
142+
143+
```
144+
145+
Get best combinations of permutations between yourself and the elephant:
146+
147+
```{r}
148+
149+
el_best |>
150+
rename(el_valves = valves, el_pressure = pressure) |>
151+
pmap_dbl(\(el_valves, el_pressure) {
152+
el_valves <- el_valves[el_valves != "AA"]
153+
el_pressure + el_best |>
154+
filter(map_lgl(valves, ~ length(intersect(.x, el_valves)) == 0)) |>
155+
pull(pressure) |>
156+
max()
157+
}) |>
158+
max()
37159
38-
plot(edges)
39160
```
40161

2022/R/day17.qmd

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
---
2+
title: "Day 17"
3+
date: 2022-12-17
4+
author:
5+
name: https://adventofcode.com/2022/day/17
6+
url: https://adventofcode.com/2022/day/17
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/day17.txt", skip_empty_rows = TRUE)
18+
19+
```
20+
21+
```{r}
22+
23+
```
24+

2022/input/day16.txt

Lines changed: 61 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,61 @@
1-
Valve AA has flow rate=0; tunnels lead to valves DD, II, BB
2-
Valve BB has flow rate=13; tunnels lead to valves CC, AA
3-
Valve CC has flow rate=2; tunnels lead to valves DD, BB
4-
Valve DD has flow rate=20; tunnels lead to valves CC, AA, EE
5-
Valve EE has flow rate=3; tunnels lead to valves FF, DD
6-
Valve FF has flow rate=0; tunnels lead to valves EE, GG
7-
Valve GG has flow rate=0; tunnels lead to valves FF, HH
8-
Valve HH has flow rate=22; tunnel leads to valve GG
9-
Valve II has flow rate=0; tunnels lead to valves AA, JJ
10-
Valve JJ has flow rate=21; tunnel leads to valve II
1+
Valve RT has flow rate=0; tunnels lead to valves EN, LZ
2+
Valve VB has flow rate=0; tunnels lead to valves SZ, BF
3+
Valve AD has flow rate=0; tunnels lead to valves EB, JF
4+
Valve RE has flow rate=4; tunnels lead to valves QB, IF, XT, WF, KW
5+
Valve RL has flow rate=0; tunnels lead to valves DQ, LZ
6+
Valve OK has flow rate=0; tunnels lead to valves QH, BF
7+
Valve RV has flow rate=0; tunnels lead to valves IU, JF
8+
Valve TE has flow rate=0; tunnels lead to valves HE, XF
9+
Valve WW has flow rate=0; tunnels lead to valves QH, YZ
10+
Valve HB has flow rate=15; tunnel leads to valve OM
11+
Valve IY has flow rate=14; tunnels lead to valves UH, KW, BN, LW, UY
12+
Valve QF has flow rate=0; tunnels lead to valves JF, PL
13+
Valve YZ has flow rate=0; tunnels lead to valves JG, WW
14+
Valve QB has flow rate=0; tunnels lead to valves SP, RE
15+
Valve SO has flow rate=0; tunnels lead to valves QH, SZ
16+
Valve EB has flow rate=7; tunnels lead to valves IF, NH, AD, VI, DQ
17+
Valve VL has flow rate=0; tunnels lead to valves JF, YV
18+
Valve BF has flow rate=18; tunnels lead to valves OK, VB, OH, SX
19+
Valve UC has flow rate=0; tunnels lead to valves SC, YV
20+
Valve OQ has flow rate=0; tunnels lead to valves XT, AA
21+
Valve YV has flow rate=6; tunnels lead to valves YX, TT, VL, UC, NH
22+
Valve KJ has flow rate=0; tunnels lead to valves OH, JG
23+
Valve QH has flow rate=20; tunnels lead to valves SO, OK, WW
24+
Valve KW has flow rate=0; tunnels lead to valves RE, IY
25+
Valve PL has flow rate=0; tunnels lead to valves JG, QF
26+
Valve DQ has flow rate=0; tunnels lead to valves EB, RL
27+
Valve AA has flow rate=0; tunnels lead to valves YI, EN, UK, OQ, VI
28+
Valve XT has flow rate=0; tunnels lead to valves OQ, RE
29+
Valve SZ has flow rate=24; tunnels lead to valves VB, SO
30+
Valve IU has flow rate=25; tunnels lead to valves RV, HE, HQ
31+
Valve OM has flow rate=0; tunnels lead to valves NY, HB
32+
Valve YX has flow rate=0; tunnels lead to valves YV, SI
33+
Valve SX has flow rate=0; tunnels lead to valves ZB, BF
34+
Valve KD has flow rate=0; tunnels lead to valves XF, LW
35+
Valve SP has flow rate=0; tunnels lead to valves XF, QB
36+
Valve UY has flow rate=0; tunnels lead to valves UK, IY
37+
Valve XF has flow rate=22; tunnels lead to valves SP, TE, KD, NY
38+
Valve SC has flow rate=0; tunnels lead to valves LZ, UC
39+
Valve UK has flow rate=0; tunnels lead to valves UY, AA
40+
Valve LW has flow rate=0; tunnels lead to valves KD, IY
41+
Valve FL has flow rate=0; tunnels lead to valves BN, LZ
42+
Valve VI has flow rate=0; tunnels lead to valves AA, EB
43+
Valve HW has flow rate=0; tunnels lead to valves JF, CY
44+
Valve YI has flow rate=0; tunnels lead to valves AA, TT
45+
Valve HE has flow rate=0; tunnels lead to valves IU, TE
46+
Valve JG has flow rate=10; tunnels lead to valves PL, YZ, SI, KJ
47+
Valve BN has flow rate=0; tunnels lead to valves IY, FL
48+
Valve IF has flow rate=0; tunnels lead to valves EB, RE
49+
Valve JF has flow rate=19; tunnels lead to valves HW, QF, VL, RV, AD
50+
Valve SI has flow rate=0; tunnels lead to valves JG, YX
51+
Valve WF has flow rate=0; tunnels lead to valves LZ, RE
52+
Valve HQ has flow rate=0; tunnels lead to valves IU, UH
53+
Valve LZ has flow rate=5; tunnels lead to valves SC, FL, WF, RL, RT
54+
Valve UH has flow rate=0; tunnels lead to valves IY, HQ
55+
Valve CY has flow rate=21; tunnel leads to valve HW
56+
Valve NH has flow rate=0; tunnels lead to valves EB, YV
57+
Valve TT has flow rate=0; tunnels lead to valves YV, YI
58+
Valve OH has flow rate=0; tunnels lead to valves KJ, BF
59+
Valve EN has flow rate=0; tunnels lead to valves RT, AA
60+
Valve NY has flow rate=0; tunnels lead to valves OM, XF
61+
Valve ZB has flow rate=8; tunnel leads to valve SX

_freeze/2022/R/day16/execute-results/html.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
{
2-
"hash": "6a25bc5739310e419033dcbae5670a06",
2+
"hash": "ba1db0b8363fc37a2239575abad8dd21",
33
"result": {
44
"engine": "knitr",
5-
"markdown": "---\ntitle: \"Day 16\"\ndate: 2022-12-16\nauthor:\n name: https://adventofcode.com/2022/day/16\n url: https://adventofcode.com/2022/day/16\n---\n\n\n\n\n\n## Setup\n\n\n\n\n\n::: {.cell}\n\n```{.r .cell-code}\n# Libraries\nlibrary(tidyverse)\nlibrary(igraph)\n\n# Read input from file\ninput <- read_lines(\"../input/day16.txt\", skip_empty_rows = TRUE) |> \n unglue::unglue_data(\n c(\n \"Valve {source} has flow rate={rate}; tunnels lead to valves {target}\",\n \"Valve {source} has flow rate={rate}; tunnel leads to valve {target}\"\n ),\n convert = TRUE\n ) |> \n mutate(target = map(target, \\(x) str_split_1(x, \", \")))\n```\n:::\n\n\n\n\n\n## Part 1\n\n\n\n\n\n::: {.cell}\n\n```{.r .cell-code}\nedges <- input |>\n unnest(target) |> \n pmap(function(source, target, ...) c(source, target)) |> \n unique() |> \n unlist() |> \n make_graph(directed = TRUE)\n\nplot(edges)\n```\n\n::: {.cell-output-display}\n![](day16_files/figure-html/unnamed-chunk-1-1.png){width=672}\n:::\n:::\n",
5+
"markdown": "---\ntitle: \"Day 16\"\ndate: 2022-12-16\nauthor:\n name: https://adventofcode.com/2022/day/16\n url: https://adventofcode.com/2022/day/16\n---\n\n\n\n\n## Setup\n\n\n\n\n::: {.cell}\n\n```{.r .cell-code}\n# Libraries\nlibrary(tidyverse)\nlibrary(igraph)\n\n# Read input from file\ninput <- read_lines(\"../input/day16.txt\", skip_empty_rows = TRUE) |> \n unglue::unglue_data(\n c(\n \"Valve {source} has flow rate={rate}; tunnels lead to valves {target}\",\n \"Valve {source} has flow rate={rate}; tunnel leads to valve {target}\"\n ),\n convert = TRUE\n ) |> \n mutate(target = map(target, \\(x) str_split_1(x, \", \")))\n```\n:::\n\n\n\n\n## Part 1\n\nRepresent tunnels and valves as a graph:\n\n\n\n\n::: {.cell}\n\n```{.r .cell-code}\ng <- input |>\n unnest(target) |> \n pmap(function(source, target, ...) c(source, target)) |> \n unique() |> \n unlist() |> \n make_graph(directed = TRUE) |> \n as_undirected()\n```\n:::\n\n\n\n\nGet the list of valves with nonzero flow:\n\n\n\n\n::: {.cell}\n\n```{.r .cell-code}\nflows <- input |> \n filter(rate > 0 | source == \"AA\") |> \n select(source, rate) |> \n deframe()\n\nnon_init_flows <- flows |> \n discard_at(\"AA\")\n\nvalves <- names(flows)\n\ndists <- distances(g, valves, valves)\n```\n:::\n\n\n\n\nList all permutations of possible valves to visit with a total distance less than 30:\n\n\n\n\n::: {.cell}\n\n```{.r .cell-code}\nget_path <- function(choices, last, cur_length, max_length) {\n if (cur_length >= max_length)\n return(head(last, -1))\n if (length(choices) == 0)\n return(last)\n \n ls <- list()\n for (valve in choices) {\n ls <- append(\n ls, \n list(get_path(\n choices[choices != valve], \n c(last, valve), \n cur_length + dists[tail(last, 1), valve] + 1,\n max_length\n ))\n )\n }\n ls |> \n discard(is_null) |> \n list_flatten() |> \n unique()\n}\n\ncombos <- get_path(names(non_init_flows), names(flows[\"AA\"]), 0, 30)\n```\n:::\n\n\n\n\nCompute total pressure released for each permutation:\n\n\n\n\n::: {.cell}\n\n```{.r .cell-code}\nget_pressures <- function(paths, max_time) {\n map_dbl(paths, \\(path) {\n valve <- tail(path, -1)\n valve_lag <- head(path, -1)\n flow <- tail(flows[path], -1)\n \n dist <- map2_int(valve_lag, valve, \\(src, target) dists[src, target])\n time_start <- cumsum(dist) + 1:length(dist) + 1\n pressure <- (max_time - time_start + 1) * flow\n \n sum(pressure[time_start <= max_time])\n })\n}\n\npressures <- get_pressures(combos, 30)\n```\n:::\n\n\n\n\nFind the permutation that gives the maximum pressure:\n\n\n\n\n::: {.cell}\n\n```{.r .cell-code}\nmax_idx <- which.max(pressures)\npressures[max_idx]\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n[1] 1947\n```\n\n\n:::\n:::\n\n\n\n\n## Part 2\n\nList all permutations of possible valves to visit with a total distance less than 26:\n\n\n\n\n::: {.cell}\n\n```{.r .cell-code}\nel_combos <- get_path(names(non_init_flows), names(flows[\"AA\"]), 0, 26)\nel_pressures <- get_pressures(el_combos, 26)\n```\n:::\n\n\n\n\nFor each set of permutations, get the best pressure.\n\n\n\n\n::: {.cell}\n\n```{.r .cell-code}\nel_best <- tibble(valves = map(el_combos, sort), pressure = el_pressures) |> \n slice_max(pressure, by = valves, with_ties = FALSE)\n```\n:::\n\n\n\n\nGet best combinations of permutations between yourself and the elephant:\n\n\n\n\n::: {.cell}\n\n```{.r .cell-code}\nel_best |> \n rename(el_valves = valves, el_pressure = pressure) |> \n pmap_dbl(\\(el_valves, el_pressure) {\n el_valves <- el_valves[el_valves != \"AA\"]\n el_pressure + el_best |>\n filter(map_lgl(valves, ~ length(intersect(.x, el_valves)) == 0)) |> \n pull(pressure) |> \n max()\n }) |> \n max()\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n[1] 2556\n```\n\n\n:::\n:::\n",
66
"supporting": [
77
"day16_files"
88
],

_freeze/site_libs/quarto-listing/list.min.js

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)