library(tidyverse)
The lines have different numbers of reports, so loading it in using a
rawer method than the usual read.csv and friends:
dat <- read_lines("aoc02.txt")
head(dat)
[1] "87 90 92 95 96 93" "12 15 16 17 17" "26 27 29 31 34 36 40"
[4] "79 80 82 85 87 88 95" "17 20 22 20 23 24" "10 13 11 12 9"
That’s a vector of strings. Next, split each string on the space and
make a list of numeric vectors:
repl <- strsplit(dat, " ") |> map(as.numeric)
head(repl)
[[1]]
[1] 87 90 92 95 96 93
[[2]]
[1] 12 15 16 17 17
[[3]]
[1] 26 27 29 31 34 36 40
[[4]]
[1] 79 80 82 85 87 88 95
[[5]]
[1] 17 20 22 20 23 24
[[6]]
[1] 10 13 11 12 9
Part 1
The rules are:
- The levels are either all increasing or all decreasing.
- Any two adjacent levels differ by at least one and at most
three.
Wrap in a function:
test_report <- function(nums) {
test_diffs <- diff(nums, lag = 1, difference = 1)
all(test_diffs %in% 1:3) || all(-test_diffs %in% 1:3)
}
The answer:
res <- map_lgl(repl, test_report)
sum(res)
[1] 483
Part 2
I’m going to brute force this one and try dropping elements even if
it’s unnecessary, as I don’t have time to be clever 🙃
robust_test_report <- function(nums) {
if (test_report(nums)) {
TRUE
}
else {
res <- FALSE
for (i in 1:length(nums)) {
res <- test_report(nums[-i])
if (res)
break
}
res
}
}
And it worked:
robust_res <- map_lgl(repl, robust_test_report)
sum(robust_res)
[1] 528
LS0tDQp0aXRsZTogIkRheSAyOiBSZWQtTm9zZWQgUmVwb3J0cyINCmF1dGhvcjogQW5kaUYNCmRhdGU6IDIgRGVjIDIwMjQNCm91dHB1dDogDQogIGh0bWxfbm90ZWJvb2s6IA0KICAgIGNvZGVfZm9sZGluZzogbm9uZQ0KLS0tDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmBgYA0KDQpUaGUgbGluZXMgaGF2ZSBkaWZmZXJlbnQgbnVtYmVycyBvZiByZXBvcnRzLCBzbyBsb2FkaW5nIGl0IGluIHVzaW5nIGEgcmF3ZXIgbWV0aG9kIHRoYW4gdGhlIHVzdWFsIHJlYWQuY3N2IGFuZCBmcmllbmRzOg0KDQpgYGB7cn0NCmRhdCA8LSByZWFkX2xpbmVzKCJhb2MwMi50eHQiKQ0KYGBgDQoNCg0KYGBge3J9DQpoZWFkKGRhdCkNCmBgYA0KDQpUaGF0J3MgYSB2ZWN0b3Igb2Ygc3RyaW5ncy4gTmV4dCwgc3BsaXQgZWFjaCBzdHJpbmcgb24gdGhlIHNwYWNlIGFuZCBtYWtlIGEgbGlzdCBvZiBudW1lcmljIHZlY3RvcnM6DQoNCmBgYHtyfQ0KcmVwbCA8LSBzdHJzcGxpdChkYXQsICIgIikgfD4gbWFwKGFzLm51bWVyaWMpDQpoZWFkKHJlcGwpDQpgYGANCg0KIyMjIFBhcnQgMQ0KDQpUaGUgcnVsZXMgYXJlOg0KDQoqIFRoZSBsZXZlbHMgYXJlIGVpdGhlciBhbGwgaW5jcmVhc2luZyBvciBhbGwgZGVjcmVhc2luZy4NCiogQW55IHR3byBhZGphY2VudCBsZXZlbHMgZGlmZmVyIGJ5IGF0IGxlYXN0IG9uZSBhbmQgYXQgbW9zdCB0aHJlZS4NCg0KV3JhcCBpbiBhIGZ1bmN0aW9uOg0KDQpgYGB7cn0NCnRlc3RfcmVwb3J0IDwtIGZ1bmN0aW9uKG51bXMpIHsNCiAgdGVzdF9kaWZmcyA8LSBkaWZmKG51bXMsIGxhZyA9IDEsIGRpZmZlcmVuY2UgPSAxKQ0KICBhbGwodGVzdF9kaWZmcyAlaW4lIDE6MykgfHwgYWxsKC10ZXN0X2RpZmZzICVpbiUgMTozKSANCn0NCmBgYA0KDQpUaGUgYW5zd2VyOg0KDQpgYGB7cn0NCnJlcyA8LSBtYXBfbGdsKHJlcGwsIHRlc3RfcmVwb3J0KQ0Kc3VtKHJlcykNCmBgYA0KDQoNCiMjIyBQYXJ0IDINCg0KSSdtIGdvaW5nIHRvIGJydXRlIGZvcmNlIHRoaXMgb25lIGFuZCB0cnkgZHJvcHBpbmcgZWxlbWVudHMgZXZlbiBpZiBpdCdzIHVubmVjZXNzYXJ5LCBhcyBJIGRvbid0IGhhdmUgdGltZSB0byBiZSBjbGV2ZXIg8J+Zgw0KDQpgYGB7cn0NCnJvYnVzdF90ZXN0X3JlcG9ydCA8LSBmdW5jdGlvbihudW1zKSB7DQogIGlmICh0ZXN0X3JlcG9ydChudW1zKSkgew0KICAgIFRSVUUNCiAgfQ0KICBlbHNlIHsNCiAgICByZXMgPC0gRkFMU0UNCiAgICBmb3IgKGkgaW4gMTpsZW5ndGgobnVtcykpIHsNCiAgICAgIHJlcyA8LSB0ZXN0X3JlcG9ydChudW1zWy1pXSkNCiAgICAgIGlmIChyZXMpDQogICAgICAgIGJyZWFrDQogICAgfQ0KICAgIHJlcw0KICB9DQp9DQpgYGANCg0KQW5kIGl0IHdvcmtlZDoNCg0KYGBge3J9DQpyb2J1c3RfcmVzIDwtIG1hcF9sZ2wocmVwbCwgcm9idXN0X3Rlc3RfcmVwb3J0KQ0Kc3VtKHJvYnVzdF9yZXMpDQpgYGANCg0KDQoNCg0K