-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday_09.Rmd
97 lines (76 loc) · 2.58 KB
/
day_09.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
93
94
95
96
97
# Encoding Error
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
options(crayon.enabled = NULL)
library(tidyverse)
START_TIME <- Sys.time()
```
This is my attempt to solve [Day 9](https://adventofcode.com/2020/day/9).
```{r load data}
sample <- read_lines("samples/day_09_sample.txt") %>% as.numeric()
actual <- read_lines("inputs/day_09_input.txt") %>% as.numeric()
```
## Part 1
We can solve part 1 by creating a function that slides a window (`r`) across the `input` and checks to see if the value
of the element `i` just after the end of the current window, minus all of the values in that window, is in the window.
```{r part 1 function}
part_1 <- function(input, n) {
i <- n + 1
r <- 1:n
while (any((input[[i]] - input[r]) %in% input[r])) {
r <- r + 1
i <- i + 1
}
input[[i]]
}
```
We can now check our function gives us the right answer for the sample:
```{r part 1 sample test}
ps1 <- part_1(sample, 5)
ps1 == 127
```
This gives us the correct answer, so we can now run on the actual input:
```{r part 1 actual}
pa1 <- part_1(actual, 25)
pa1
```
## Part 2
The naive approach here is to start to use nested for loops to sum the values. There is probably a smarter way of
solving this, but it's the approach I will use.
Instead of using the `sum`, `min` and `max` functions available in R I am going to keep track of the values: this should
give us a slight performance boost by not having to iterate through all of the values each time.
```{r part 2 solve}
part_2 <- function(input, t) {
s <- which(input == t)
# we need to loop until just before the index of the target in the input
# as we are using nested loops it should be s - 2 here
for (i in 1:(s - 2)) {
sv <- input[[i]] # keep track of the sum
minv <- sv # and the min value
maxv <- sv # and the max value
# now we need to loop from the next value (i + 1) to just before the target
for (j in (i + 1):(s - 1)) {
# update the sum
sv <- sv + input[[j]]
# if we exceed the target then break out the loop and move to the next i
if (sv > t) next()
# update the min and max values
if (input[[j]] < minv) minv <- input[[j]]
if (input[[j]] > maxv) maxv <- input[[j]]
# if our sum is equal to the target, then return the sum of the min and
# max value
if (sv == t) return (minv + maxv)
}
}
}
```
We can test on the sample:
```{r part 2 sample test}
part_2(sample, ps1) == 62
```
And run on the actual input:
```{r part 2 sample actual}
part_2(actual, pa1)
```
---
*Elapsed Time: `r round(Sys.time() - START_TIME, 3)`s*