Spiral matrix: Difference between revisions

→‎{{header|R}}: New iterative solution. Finished at 1am, so possibily in need of tidying.
(alt impl for Lua)
(→‎{{header|R}}: New iterative solution. Finished at 1am, so possibily in need of tidying.)
Line 4,010:
 
=={{header|R}}==
===Sequence Solution===
<lang R>spiral_matrix <- function(n) {
stopifnot(is.numeric(n))
Line 4,053 ⟶ 4,054:
}
spiralv(1:(n^2))
}</lang>
 
===Iterative Solution===
Not the most elegant, but certainly distinct from the other R solutions. The key is the observation that we need to produce n elements from left to right, then n-1 elements down, then n-1 left, then n-2 right, then n-2 down, ... . This gives us two patterns. One in the direction that we need to write and another in the number of elements to write. After this, all that is left is battling R's indexing system.
<lang R>spiralMatrix<-function(n)
{
spiral<-matrix(0,nrow=n,ncol=n)
firstNumToWrite<-0
neededLength<-n
startPt<-cbind(1,0)#(1,0) is needed for the first call to writeRight to work. We need to start in row 1.
writingDirectionIndex<-0
#These two functions select a collection of adjacent elements and replaces them with the needed sequence.
#This heavily uses R's vector recycling rules.
writeDown<-function(seq){spiral[startPt[1]+seq,startPt[2]]<<-seq_len(neededLength)-1+firstNumToWrite}
writeRight<-function(seq){spiral[startPt[1],startPt[2]+seq]<<-seq_len(neededLength)-1+firstNumToWrite}
while(firstNumToWrite!=n^2)
{
writingDirectionIndex<-writingDirectionIndex%%4 + 1
seq<-1:neededLength
switch(writingDirectionIndex,
writeRight(seq),
writeDown(seq),
writeRight(-seq),
writeDown(-seq))
if(writingDirectionIndex%%2==1){neededLength<-neededLength-1}
max<-max(spiral)
firstNumToWrite<-max+1
startPt<-which(max==spiral,arr.ind = TRUE)
}
spiral
}</lang>
 
331

edits