Little useless-useful R functions – Return matrix elements in spiral order

Another one from the Leetcode challenge. This time, get the elements (single values) from the matrix in a spiral order with a starting position of [1,1].

So, the basic idea is to retrieve a vector of elements from a matrix in the following order:

In this order, we get the vector with the following elements:

So, we need to create the boundaries, count the rows | columns and return a vector of elements. Here is the useless function:

## return elements from matrix in spiral order
matrix_spiral <- function(mat) {
  mr <- dim(mat)[1]
  nc <- dim(mat)[2]
  total_len <- mr*nc

  #path #TRUE -> visited; FALSE -> unvisited
  visit <- matrix(FALSE, nrow=mr, ncol=nc)
  
  #helper variables
  gor <- 1
  dol <- mr
  levo <- 1
  desno <- nc
  res <- vector()
  
  while (length(res) < total_len) {

    for (i in levo:nc) {
      if (!visit[gor, i]) {
          res <- c(res, mat[gor,i])
          visit[gor, i] <- TRUE
      } }
    gor <- gor + 1

    for (i in gor:mr) {
      if (!visit[i, desno]) {
          res <- c(res, mat[i,desno])
          visit[i, desno] <- TRUE
      } }
    desno <- desno - 1
    
    if (gor <= dol) {
      for (i in desno:levo) {
        if (!visit[dol, i]) {
          res <- c(res, mat[dol,i])
          visit[dol, i] <- TRUE
        } }
      dol <- dol - 1
    }
    
    if (levo <= desno) {
      for (i in dol:gor) {
        if (!visit[i, levo]) {
            res <- c(res, mat[i,levo])
            visit[i, levo] <- TRUE
        } }
    levo <- levo + 1
    } }
  return(res)
}

As always, the complete code is available on Github in  Useless_R_function repository. The sample file in this repository is here (filename: Spiral_matrix.R). Check the repository for future updates.

Happy R-coding and stay healthy!

Tagged with: , , , ,
Posted in R, Useless R functions
4 comments on “Little useless-useful R functions – Return matrix elements in spiral order
  1. […] article was first published on R – TomazTsql, and kindly contributed to R-bloggers]. (You can report issue about the content on this page […]

    Like

  2. […] Tomaz Kastrun forgot to remove The Club from his REPL: […]

    Like

  3. carlwitthoft says:

    Hmmm… seems (without analytic justification) that there should be an algorithm which, treating the array as a vector, generates the re-ordered indices automatically. I’ll have to look for some such.

    Like

  4. carlwitthoft says:

    I finished it! This code runs way faster than the original. I’ll leave future improvements up to the fan-base.
    spirMat <- function(mat, handed = c('left','right'),…){
    #later: more input validation
    mdim <- base::dim(mat) # so I can bail if not an array
    inCount <- 1:length(mat) # to be used later
    # which way?
    if (handed =='right') x <- x[,ncol(x):1]
    # hmmm, save some heavy thinking by using a matching index array
    # this will have values matching the index order in as.vector(imat)
    imat <- array(1:length(mat),c(mdim[1],mdim[2]))
    mseq <- iseq <- NULL
    nrow <- mdim[1]
    ncol <- mdim[2]
    # use indexing to get actual array values, which for iseq magically are teh same as the locations…
    vecmat <- as.vector(t(mat))
    ivecmat 2 && ncol > 2) {
    iseq <- c( iseq, ivecmat[c(1:ncol, ncol*(2:nrow), (nrow-1)*(ncol)+(ncol-1):1, ((nrow-2):1)* ncol + 1)])
    mseq <- c(mseq, vecmat[c(1:ncol, ncol*(2:nrow), (nrow-1)*(ncol)+(ncol-1):1, ((nrow-2):1)* ncol + 1)])
    mat <- mat[2:(nrow-1),2:(ncol-1),drop=FALSE]
    vecmat <- as.vector(t(mat))
    imat <- imat[2:(nrow-1),2:(ncol-1),drop=FALSE]
    ivecmat <- as.vector(t(imat))
    # here we catch a 1xN or Nx1 remaining bit
    if (nrow(mat) ==1 || ncol(mat) == 1) {
    mseq <- c(mseq, as.vector(mat))
    iseq <- c(iseq, as.vector(t(imat)))
    } else {
    nrow <- nrow -2
    ncol <- ncol -2
    # check for exactly 2 rows
    if(nrow(mat) == 2 ) {
    # for 2xN don't want 4th term used in ncol == 2 section
    iseq <- c(iseq, ivecmat[c(1:ncol, ncol*(2:nrow), (nrow-1)*(ncol)+(ncol-1):1)])
    mseq <- c(mseq, vecmat[c(1:ncol, ncol*(2:nrow), (nrow-1)*(ncol)+(ncol-1):1)])
    } else {
    #exactly 2 columns
    if( ncol(mat) == 2) {
    iseq <- c( iseq, ivecmat[c(1:ncol, ncol*(2:nrow), (nrow-1)*(ncol)+(ncol-1):1, ((nrow-2):1)* ncol + 1)])
    mseq <- c(mseq, vecmat[c(1:ncol, ncol*(2:nrow), (nrow-1)*(ncol)+(ncol-1):1, ((nrow-2):1)* ncol + 1)])
    }
    }
    } #end of outer else
    } #end while
    return(invisible(list(spiral = mseq, idx = iseq)))
    }

    Like

Leave a comment

Follow TomazTsql on WordPress.com
Programs I Use: SQL Search
Programs I Use: R Studio
Programs I Use: Plan Explorer
Rdeči Noski – Charity

Rdeči noski

100% of donations made here go to charity, no deductions, no fees. For CLOWNDOCTORS - encouraging more joy and happiness to children staying in hospitals (http://www.rednoses.eu/red-noses-organisations/slovenia/)

€2.00

Top SQL Server Bloggers 2018
TomazTsql

Tomaz doing BI and DEV with SQL Server and R, Python, Power BI, Azure and beyond

Discover WordPress

A daily selection of the best content published on WordPress, collected for you by humans who love to read.

Revolutions

Tomaz doing BI and DEV with SQL Server and R, Python, Power BI, Azure and beyond

tenbulls.co.uk

tenbulls.co.uk - attaining enlightenment with the Microsoft Data and Cloud Platforms with a sprinkling of Open Source and supporting technologies!

SQL DBA with A Beard

He's a SQL DBA and he has a beard

Reeves Smith's SQL & BI Blog

A blog about SQL Server and the Microsoft Business Intelligence stack with some random Non-Microsoft tools thrown in for good measure.

SQL Server

for Application Developers

Business Analytics 3.0

Data Driven Business Models

SQL Database Engine Blog

Tomaz doing BI and DEV with SQL Server and R, Python, Power BI, Azure and beyond

Search Msdn

Tomaz doing BI and DEV with SQL Server and R, Python, Power BI, Azure and beyond

R-bloggers

Tomaz doing BI and DEV with SQL Server and R, Python, Power BI, Azure and beyond

R-bloggers

R news and tutorials contributed by hundreds of R bloggers

Data Until I Die!

Data for Life :)

Paul Turley's SQL Server BI Blog

sharing my experiences with the Microsoft data platform, SQL Server BI, Data Modeling, SSAS Design, Power Pivot, Power BI, SSRS Advanced Design, Power BI, Dashboards & Visualization since 2009

Grant Fritchey

Intimidating Databases and Code

Madhivanan's SQL blog

A modern business theme

Alessandro Alpi's Blog

DevOps could be the disease you die with, but don’t die of.

Paul te Braak

Business Intelligence Blog

Sql Insane Asylum (A Blog by Pat Wright)

Information about SQL (PostgreSQL & SQL Server) from the Asylum.

Gareth's Blog

A blog about Life, SQL & Everything ...