Skip to content

Instantly share code, notes, and snippets.

@artemklevtsov
Last active May 20, 2016 05:42
Show Gist options
  • Save artemklevtsov/ea07ab03a077810df0fc to your computer and use it in GitHub Desktop.
Save artemklevtsov/ea07ab03a077810df0fc to your computer and use it in GitHub Desktop.
#include <Rcpp.h>
// [[Rcpp::export]]
Rcpp::NumericMatrix rcpp_spiral(std::size_t nrow, std::size_t ncol) {
Rcpp::NumericMatrix res(nrow, ncol); // result matrix
int dx[4] = {0, 1, 0, -1}; // shift by rows
int dy[4] = {1, 0, -1, 0}; // shift by columns
int x = 0, y = -1; // init coordinates
std::size_t num = 1; // numbers to fill: 1...nrow * ncol
int side, len;
for (std::size_t i = 0; i < nrow + ncol - 1; i++) {
side = i % 4; // matrix side: 0, 1, 2, 3
if (side % 2 == 1) // if side is not even
len = (nrow + nrow - i) / 2; // row limit
else
len = (ncol + ncol - i) / 2; // column limit
for (std::size_t j = 0; j < len && num <= nrow * ncol; j++) {
x += dx[side]; // shift row
y += dy[side]; // shift column
res(x, y) = num++;
}
}
return res;
}
spiral <- function(n) {
stopifnot(is.numeric(n))
stopifnot(n > 0)
offset <- c(1, n, -1, -n)
reps <- n - seq_len(n * 2 - 1L) %/% 2
indicies <- rep(rep_len(offset, length(reps)), reps)
indicies <- cumsum(indicies)
values <- integer(length(indicies))
values[indicies] <- seq_along(indicies)
matrix(values, n, n, byrow = TRUE)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment