To install `mistlecode` yourself, run `devtools::install_github('guslipkin/mistlecode')`.
Also loading: cipheR data.table dplyr purrr slider stringr tidyverse glue
05: How About a Nice Game of Chess?
I initially did everything in pure R
, but it was kinda slow and the solution seemed easy enough to dip my toes into Rcpp
. All things considered, it went pretty smoothly. Some of the trickier bits were getting the StringVector
<>std::string
relationship straight, and not crashing everything when trying to sub-string a StringVector
with string_vector[x][y]
which is why I ended up just using std::string
.
After re-writing, I was able to speed up Part 1 by ~37 seconds and Part 2 by ~ 10 minutes…
Part 1
This isn’t as bad as it looks. Only annoying thing was serialize = FALSE
but StackOverflow cleared that up pretty quick.
cppFunction('
StringVector part1(StringVector dt) {
std::string string_x, dig, string_dt = as<std::string>(dt);
StringVector password(8);
int x = 0, j = 0, p_size = password.size();
Function md5("digest");
Function paste0("paste0");
while (j < p_size) {
string_x = std::to_string(x);
dig = string_dt + string_x;
dig = as<std::string>(md5(dig, _["algo"]="md5", _["serialize"]=0));
if (dig.substr(0, 5) == "00000") {
password[j] = dig.substr(5, 1);
j++;
}
//if (x % 100000 == 0) { std::cout << "\\r" << string_x << password; }
x++;
}
std::cout << std::endl;
return paste0(password, _["collapse"]="");
}
')
part1(dt)
[1] "f97c354d"
Part 2
That’s not so bad. Just a few small changes and a lot slower…
cppFunction('
StringVector part2(StringVector dt) {
std::string string_x, dig, string_dt = as<std::string>(dt);
StringVector password(8);
int x = 0, j = 0, p_size = password.size(), int_six;
Function md5("digest");
Function paste0("paste0");
while (j < p_size) {
string_x = std::to_string(x);
dig = string_dt + string_x;
dig = as<std::string>(md5(dig, _["algo"]="md5", _["serialize"]=0));
if (dig.substr(0, 5) == "00000") {
try {
int_six = stoi(dig.substr(5, 1));
} catch(...) {
int_six = -1;
}
if (int_six > -1 && int_six < p_size && password[int_six] == "") {
password[int_six] = dig.substr(6, 1);
j++;
}
}
//if (x % 100000 == 0) { std::cout << "\\r" << string_x << password; }
x++;
}
std::cout << std::endl;
return paste0(password, _["collapse"]="");
}
')
old <- Sys.time()
part2(dt)
[1] "863dde27"
Time difference of 4.88216 mins
old <- Sys.time()
x <- 0
password <- rep("", 8)
while(any(password == "")) {
dig <-
paste0(dt, x) |>
digest::digest(algo = "md5", serialize = FALSE)
z <-
dig |>
substr(6, 6) |>
as.numeric() |>
suppressWarnings()
if (
substr(dig, 1, 5) == "00000" & !is.na(z) &
!is.na(password[z + 1]) & password[z + 1] == "") {
password[z + 1] <- substr(dig, 7, 7)
}
x <- x + 1
}
paste0(password, collapse = "")
Sys.time() - old