-
Notifications
You must be signed in to change notification settings - Fork 1
/
day19.Rmd
92 lines (88 loc) · 2.16 KB
/
day19.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
---
title: "--- Day 19: Monster Messages ---"
author: Fleur Kelpin
date: Dec 19, 2020
output: github_document
---
```{r message=FALSE, warning=FALSE}
library(tidyverse)
input <- tibble(line = readLines("day19-rules.txt")) %>%
extract(line, c("number", "rules"), "(\\d+): (.*)") %>%
extract(rules, "letters", "\"(\\w)\"", remove = F) %>%
extract(rules, c("alt1", NA, "alt2"), "([0-9 ]*)(\\|(.*))?") %>%
mutate(number = as.integer(number)) %>%
extract(alt1, c("alt1a", "alt1b"), "([0-9]+)( [0-9]+)?", convert = T) %>%
extract(alt2, c("alt2a", "alt2b"), "([0-9]+)( [0-9]+)?", convert = T) %>%
arrange(number)
input
messages <- tibble(message = readLines("day19-messages.txt"))
messages
```
# Part 1
```{r}
getMessages <- function(num) {
if (is.na(num)) {
return(character())
}
rule <- input %>% filter(number == num)
letters <- rule$letters[[1]]
if (!is.na(letters)) {
return(letters)
}
alt1a <- rule$alt1a[[1]]
alt1b <- rule$alt1b[[1]]
alt2a <- rule$alt2a[[1]]
alt2b <- rule$alt2b[[1]]
if (!is.na(alt2a)) {
union(
getMessagesAB(alt1a, alt1b),
getMessagesAB(alt2a, alt2b)
) %>%
unique()
} else {
getMessagesAB(alt1a, alt1b)
}
}
getMessagesAB <- function(pre, post) {
a <- getMessages(pre)
if (is.na(post)) {
return(a)
}
b <- getMessages(post)
crossing(a, b) %>%
mutate(x = paste0(a, b)) %>%
{
.$x
} %>%
unique()
}
```
```{r}
messages$message %>%
intersect(getMessages(0)) %>%
length()
```
# Part 2
As you look over the list of messages, you realize your matching rules aren't quite right. To fix them, completely replace rules 8: 42 and 11: 42 31 with the following:
```
8: 42 | 42 8
11: 42 31 | 42 11 31
```
The other relevant rule is `0: 8 11`
```{r}
getRegex <- function(num) {
getMessages(num) %>%
paste(collapse = "|") %>%
{paste0("(", ., ")")}
}
reg42 <- getRegex(42)
reg11 <- getRegex(11)
reg31 <- getRegex(31)
regex <- paste0("^", reg42, "+((", reg42, reg31, ")|(", reg42, "{2}", reg31,
"{2})|(", reg42, "{3}", reg31, "{3})|(", reg42, "{4}", reg31,
"{4}))$")
messages %>%
rowwise() %>%
filter(str_detect(message, regex)) %>%
nrow()
```