Spiral matrix: Difference between revisions

m
 
(126 intermediate revisions by 36 users not shown)
Line 1:
{{task|Matrices}}
Produce a spiral array. <br>
A spiral array is a square arrangement of the
first <tt>N<sup>2</sup></tt> natural numbers,
where the numbers increase sequentially
as you go around the edges of the array spiralling inwards.
 
;Task:
For example, given 5, produce this array:
Produce a spiral array.
 
 
A &nbsp; ''spiral array'' &nbsp; is a square arrangement of the first &nbsp; <big> N<sup>2</sup></big> &nbsp; natural numbers, &nbsp; where the
<br>numbers increase sequentially as you go around the edges of the array spiraling inwards.
 
 
For example, given &nbsp; '''5''', &nbsp; produce this array:
<pre>
0 1 2 3 4
Line 15 ⟶ 18:
</pre>
 
 
;See also [[Zig-zag matrix]]
;Related tasks:
* &nbsp; [[Zig-zag matrix]]
* &nbsp; [[Identity_matrix]]
* &nbsp; [[Ulam_spiral_(for_primes)]]
<br><br>
 
=={{header|11l}}==
{{trans|Python}}
 
<syntaxhighlight lang="11l">F spiral_matrix(n)
V m = [[0] * n] *n
V d = [(0, 1), (1, 0), (0, -1), (-1, 0)]
V xy = (0, -1)
V c = 0
L(i) 0 .< n + n - 1
L 0 .< (n + n - i) I/ 2
xy += d[i % 4]
m[xy.x][xy.y] = c
c++
R m
 
F printspiral(myarray)
L(y) 0 .< myarray.len
L(x) 0 .< myarray.len
print(‘#2’.format(myarray[y][x]), end' ‘ ’)
print()
 
printspiral(spiral_matrix(5))</syntaxhighlight>
 
{{out}}
<pre>
0 1 2 3 4
15 16 17 18 5
14 23 24 19 6
13 22 21 20 7
12 11 10 9 8
</pre>
 
=={{header|360 Assembly}}==
For maximum compatibility, this program uses only the basic instruction set.
{{trans|BBC BASIC}}
<langsyntaxhighlight lang="360asm">SPIRALM CSECT
USING SPIRALM,R13
SAVEAREA B STM-SAVEAREA(R15)
Line 139 ⟶ 179:
MATRIX DS H Matrix(n,n)
YREGS
END SPIRALM</langsyntaxhighlight>
{{out}}
<pre> 0 1 2 3 4
Line 146 ⟶ 186:
13 22 21 20 7
12 11 10 9 8</pre>
 
=={{header|ABAP}}==
 
<syntaxhighlight lang="abap">REPORT zspiral_matrix.
 
CLASS lcl_spiral_matrix DEFINITION FINAL.
PUBLIC SECTION.
 
TYPES:
BEGIN OF ty_coordinates,
dy TYPE i,
dx TYPE i,
value TYPE i,
END OF ty_coordinates,
ty_t_coordinates TYPE STANDARD TABLE OF ty_coordinates WITH EMPTY KEY.
 
DATA mv_dimention TYPE i.
DATA mv_initial_value TYPE i.
 
METHODS:
constructor IMPORTING iv_dimention TYPE i
iv_initial_value TYPE i,
 
get_coordinates RETURNING VALUE(rv_result) TYPE ty_t_coordinates,
 
print.
 
PRIVATE SECTION.
DATA lt_coordinates TYPE ty_t_coordinates.
 
METHODS create RETURNING VALUE(ro_result) TYPE REF TO lcl_spiral_matrix.
 
ENDCLASS.
 
CLASS lcl_spiral_matrix IMPLEMENTATION.
METHOD constructor.
 
mv_dimention = iv_dimention.
mv_initial_value = iv_initial_value.
 
create( ).
 
ENDMETHOD.
 
METHOD create.
 
DATA dy TYPE i.
DATA dx TYPE i.
DATA value TYPE i.
DATA seq_number TYPE i.
DATA seq_dimention TYPE i.
DATA sign_coef TYPE i VALUE -1.
 
value = mv_initial_value.
 
" Fill in the first row (index 0)
DO mv_dimention TIMES.
APPEND VALUE #( dy = dy dx = dx value = value ) TO lt_coordinates.
value = value + 1.
dx = dx + 1.
ENDDO.
 
seq_dimention = mv_dimention.
 
" Find the row and column numbers and set the values.
DO ( 2 * mv_dimention - 2 ) / 2 TIMES.
sign_coef = - sign_coef.
seq_dimention = seq_dimention - 1.
 
DO 2 TIMES.
seq_number = seq_number + 1.
 
DO seq_dimention TIMES.
 
IF seq_number MOD 2 <> 0.
dy = dy + 1 * sign_coef.
ELSE.
dx = dx - 1 * sign_coef.
ENDIF.
 
APPEND VALUE #( dy = dy dx = dx value = value ) TO lt_coordinates.
value = value + 1.
ENDDO.
 
ENDDO.
 
ENDDO.
 
ro_result = me.
 
ENDMETHOD.
 
METHOD get_coordinates.
rv_result = lt_coordinates.
ENDMETHOD.
 
METHOD print.
 
DATA cnt TYPE i.
DATA line TYPE string.
 
SORT lt_coordinates BY dy dx ASCENDING.
 
LOOP AT lt_coordinates ASSIGNING FIELD-SYMBOL(<ls_coordinates>).
 
cnt = cnt + 1.
line = |{ line } { <ls_coordinates>-value }|.
 
IF cnt MOD mv_dimention = 0.
WRITE / line.
CLEAR line.
ENDIF.
 
ENDLOOP.
 
ENDMETHOD.
 
ENDCLASS.
 
START-OF-SELECTION.
 
DATA(go_spiral_matrix) = NEW lcl_spiral_matrix( iv_dimention = 5
iv_initial_value = 0 ).
go_spiral_matrix->print( ).</syntaxhighlight>
 
{{out}}
<pre>
0 1 2 3 4
15 16 17 18 5
14 23 24 19 6
13 22 21 20 7
12 11 10 9 8
</pre>
 
[https://github.com/victorizbitskiy/abapSpiralMatrix/blob/main/docs/img/Result.png Screenshot from ABAP system]
 
=={{header|Action!}}==
<syntaxhighlight lang="action!">DEFINE MAX_SIZE="10"
DEFINE MAX_MATRIX_SIZE="100"
 
INT FUNC Index(BYTE size,x,y)
RETURN (x+y*size)
 
PROC PrintMatrix(BYTE ARRAY a BYTE size)
BYTE i,j,v
FOR j=0 TO size-1
DO
FOR i=0 TO size-1
DO
v=a(Index(size,i,j))
IF v<10 THEN
Print(" ")
ELSE
Print(" ")
FI
PrintB(v)
OD
PutE()
OD
RETURN
 
PROC FillMatrix(BYTE ARRAY a BYTE size)
INT lev,maxLev,dist,maxDist,v
 
maxLev=size/2
IF (size&1)=0 THEN
maxLev==-1
FI
maxDist=size-1
v=1
FOR lev=0 TO maxLev
DO
FOR dist=0 TO maxDist
DO
a(Index(size,lev+dist,lev))=v v==+1
OD
FOR dist=0 TO maxDist-1
DO
a(Index(size,size-1-lev,lev+dist+1))=v v==+1
OD
FOR dist=0 TO maxDist-1
DO
a(Index(size,size-2-lev-dist,size-1-lev))=v v==+1
OD
FOR dist=0 TO maxDist-2
DO
a(Index(size,lev,size-2-lev-dist))=v v==+1
OD
maxDist==-2
OD
RETURN
 
PROC Test(BYTE size)
BYTE ARRAY mat(MAX_MATRIX_SIZE)
PrintF("Matrix size: %B%E",size)
FillMatrix(mat,size)
PrintMatrix(mat,size)
PutE()
RETURN
 
PROC Main()
Test(5)
Test(6)
RETURN</syntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Spiral_matrix.png Screenshot from Atari 8-bit computer]
<pre>
Matrix size: 5
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
 
Matrix size: 6
1 2 3 4 5 6
20 21 22 23 24 7
19 32 33 34 25 8
18 31 36 35 26 9
17 30 29 28 27 10
16 15 14 13 12 11
</pre>
 
=={{header|Ada}}==
<langsyntaxhighlight lang="ada">-- Spiral Square
with Ada.Text_Io; use Ada.Text_Io;
with Ada.Integer_Text_Io; use Ada.Integer_Text_Io;
Line 214 ⟶ 478:
begin
Print(Spiral(5));
end Spiral_Square;</langsyntaxhighlight>
The following is a variant using a different algorithm (which can also be used recursively):
<langsyntaxhighlight lang="ada">function Spiral (N : Positive) return Array_Type is
Result : Array_Type (1..N, 1..N);
Left : Positive := 1;
Line 248 ⟶ 512:
Result (Top, Left) := Index;
return Result;
end Spiral;</langsyntaxhighlight>
 
=={{header|ALGOL 68}}==
Line 255 ⟶ 519:
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-1.18.0/algol68g-1.18.0-9h.tiny.el5.centos.fc11.i386.rpm/download 1.18.0-9h.tiny]}}
{{works with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d]}}
<langsyntaxhighlight lang="algol68">INT empty=0;
 
PROC spiral = (INT n)[,]INT: (
Line 288 ⟶ 552:
);
print spiral(spiral(5))</langsyntaxhighlight>
{{out}}
<pre>
Line 297 ⟶ 561:
13 12 11 10 9
</pre>
 
=={{header|AppleScript}}==
 
{{Trans|JavaScript}} (ES6)
<syntaxhighlight lang="applescript">---------------------- SPIRAL MATRIX ---------------------
 
-- spiral :: Int -> [[Int]]
on spiral(n)
script go
on |λ|(rows, cols, start)
if 0 < rows then
{enumFromTo(start, start + pred(cols))} & ¬
map(my |reverse|, ¬
transpose(|λ|(cols, pred(rows), start + cols)))
else
{{}}
end if
end |λ|
end script
go's |λ|(n, n, 0)
end spiral
 
 
--------------------------- TEST -------------------------
on run
wikiTable(spiral(5), ¬
false, ¬
"text-align:center;width:12em;height:12em;table-layout:fixed;")
end run
 
 
-------------------- WIKI TABLE FORMAT -------------------
 
-- wikiTable :: [Text] -> Bool -> Text -> Text
on wikiTable(lstRows, blnHdr, strStyle)
script fWikiRows
on |λ|(lstRow, iRow)
set strDelim to if_(blnHdr and (iRow = 0), "!", "|")
set strDbl to strDelim & strDelim
linefeed & "|-" & linefeed & strDelim & space & ¬
intercalateS(space & strDbl & space, lstRow)
end |λ|
end script
linefeed & "{| class=\"wikitable\" " & ¬
if_(strStyle ≠ "", "style=\"" & strStyle & "\"", "") & ¬
intercalateS("", ¬
map(fWikiRows, lstRows)) & linefeed & "|}" & linefeed
end wikiTable
 
 
------------------------- GENERIC ------------------------
 
-- comparing :: (a -> b) -> (a -> a -> Ordering)
on comparing(f)
script
on |λ|(a, b)
tell mReturn(f)
set fa to |λ|(a)
set fb to |λ|(b)
if fa < fb then
-1
else if fa > fb then
1
else
0
end if
end tell
end |λ|
end script
end comparing
 
 
-- concatMap :: (a -> [b]) -> [a] -> [b]
on concatMap(f, xs)
set lng to length of xs
set acc to {}
tell mReturn(f)
repeat with i from 1 to lng
set acc to acc & (|λ|(item i of xs, i, xs))
end repeat
end tell
if {text, string} contains class of xs then
acc as text
else
acc
end if
end concatMap
 
 
-- enumFromTo :: Int -> Int -> [Int]
on enumFromTo(m, n)
if m ≤ n then
set lst to {}
repeat with i from m to n
set end of lst to i
end repeat
return lst
else
return {}
end if
end enumFromTo
 
 
-- foldl :: (a -> b -> a) -> a -> [b] -> a
on foldl(f, startValue, xs)
tell mReturn(f)
set v to startValue
set lng to length of xs
repeat with i from 1 to lng
set v to |λ|(v, item i of xs, i, xs)
end repeat
return v
end tell
end foldl
 
 
-- if_ :: Bool -> a -> a -> a
on if_(bool, x, y)
if bool then
x
else
y
end if
end if_
 
 
-- intercalateS :: String -> [String] -> String
on intercalateS(sep, xs)
set {dlm, my text item delimiters} to {my text item delimiters, sep}
set s to xs as text
set my text item delimiters to dlm
return s
end intercalateS
 
 
-- length :: [a] -> Int
on |length|(xs)
length of xs
end |length|
 
 
-- max :: Ord a => a -> a -> a
on max(x, y)
if x > y then
x
else
y
end if
end max
 
 
-- maximumBy :: (a -> a -> Ordering) -> [a] -> a
on maximumBy(f, xs)
set cmp to mReturn(f)
script max
on |λ|(a, b)
if a is missing value or cmp's |λ|(a, b) < 0 then
b
else
a
end if
end |λ|
end script
foldl(max, missing value, xs)
end maximumBy
 
 
-- Lift 2nd class handler function into 1st class script wrapper
-- mReturn :: First-class m => (a -> b) -> m (a -> b)
on mReturn(f)
if class of f is script then
f
else
script
property |λ| : f
end script
end if
end mReturn
 
 
-- map :: (a -> b) -> [a] -> [b]
on map(f, xs)
tell mReturn(f)
set lng to length of xs
set lst to {}
repeat with i from 1 to lng
set end of lst to |λ|(item i of xs, i, xs)
end repeat
return lst
end tell
end map
 
 
-- pred :: Enum a => a -> a
on pred(x)
x - 1
end pred
 
 
-- Egyptian multiplication - progressively doubling a list, appending
-- stages of doubling to an accumulator where needed for binary
-- assembly of a target length
-- replicate :: Int -> a -> [a]
on replicate(n, a)
set out to {}
if n < 1 then return out
set dbl to {a}
repeat while (n > 1)
if (n mod 2) > 0 then set out to out & dbl
set n to (n div 2)
set dbl to (dbl & dbl)
end repeat
return out & dbl
end replicate
 
 
-- reverse :: [a] -> [a]
on |reverse|(xs)
if class of xs is text then
(reverse of characters of xs) as text
else
reverse of xs
end if
end |reverse|
 
 
-- Simplified version - assuming rows of unvarying length.
-- transpose :: [[a]] -> [[a]]
on transpose(rows)
script cols
on |λ|(_, iCol)
script cell
on |λ|(row)
item iCol of row
end |λ|
end script
concatMap(cell, rows)
end |λ|
end script
map(cols, item 1 of rows)
end transpose
 
 
-- unlines :: [String] -> String
on unlines(xs)
set {dlm, my text item delimiters} to ¬
{my text item delimiters, linefeed}
set str to xs as text
set my text item delimiters to dlm
str
end unlines
 
 
-- unwords :: [String] -> String
on unwords(xs)
intercalateS(space, xs)
end unwords</syntaxhighlight>
{{Out}}
{| class="wikitable" style="text-align:center;width:12em;height:12em;table-layout:fixed;"
|-
| 0 || 1 || 2 || 3 || 4
|-
| 15 || 16 || 17 || 18 || 5
|-
| 14 || 23 || 24 || 19 || 6
|-
| 13 || 22 || 21 || 20 || 7
|-
| 12 || 11 || 10 || 9 || 8
|}
 
=={{header|Arturo}}==
{{trans|Python}}
<syntaxhighlight lang="rebol">spiralMatrix: function [n][
m: new array.of: @[n,n] null
 
[dx, dy, x, y]: [1, 0, 0, 0]
 
loop 0..dec n^2 'i [
m\[y]\[x]: i
 
[nx,ny]: @[x+dx, y+dy]
 
if? and? [and? [in? nx 0..n-1][in? ny 0..n-1]][
null? m\[ny]\[nx]
][
[x,y]: @[nx, ny]
]
else [
bdx: dx
[dx, dy]: @[neg dy, bdx]
[x, y]: @[x+dx, y+dy]
]
]
 
return m
]
 
loop spiralMatrix 5 'row [
print map row 'x -> pad to :string x 4
]</syntaxhighlight>
 
{{out}}
 
<pre> 0 1 2 3 4
15 16 17 18 5
14 23 24 19 6
13 22 21 20 7
12 11 10 9 8</pre>
 
=={{header|AutoHotkey}}==
{{trans|Python|}}
ahk forum: [http://www.autohotkey.com/forum/post-276718.html#276718 discussion]
<langsyntaxhighlight AutoHotkeylang="autohotkey">n := 5, dx := x := y := v := 1, dy := 0
 
Loop % n*n {
Line 326 ⟶ 903:
13 12 11 10 9
---------------------------
*/</langsyntaxhighlight>
 
=={{header|AWK}}==
<syntaxhighlight lang="awk">
<lang AWK>
# syntax: GAWK -f SPIRAL_MATRIX.AWK [-v offset={0|1}] [size]
# converted from BBC BASIC
Line 369 ⟶ 946:
exit(0)
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 380 ⟶ 957:
 
=={{header|BBC BASIC}}==
<langsyntaxhighlight lang="bbcbasic"> N%=5
@%=LENSTR$(N%*N%-1)+1
BotCol%=0 : TopCol%=N%-1
Line 397 ⟶ 974:
ENDCASE
NEXT
END</langsyntaxhighlight>
 
=={{header|C}}==
Note: program produces a matrix starting from 1 instead of 0, because task says "natural numbers".
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
Line 435 ⟶ 1,012:
 
return 0;
}</langsyntaxhighlight>
 
Recursive method, width and height given on command line:
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
 
Line 455 ⟶ 1,032:
}
return 0;
}</langsyntaxhighlight>
 
=={{header|C++}}==
<lang cpp>#include <vector>
#include <memory> // for auto_ptr
#include <cmath> // for the ceil and log10 and floor functions
#include <iostream>
#include <iomanip> // for the setw function
 
using namespace std;
 
typedef vector< int > IntRow;
typedef vector< IntRow > IntTable;
 
auto_ptr< IntTable > getSpiralArray( int dimension )
{
auto_ptr< IntTable > spiralArrayPtr( new IntTable(
dimension, IntRow( dimension ) ) );
 
int numConcentricSquares = static_cast< int >( ceil(
static_cast< double >( dimension ) / 2.0 ) );
 
int j;
int sideLen = dimension;
int currNum = 0;
 
for ( int i = 0; i < numConcentricSquares; i++ )
{
// do top side
for ( j = 0; j < sideLen; j++ )
( *spiralArrayPtr )[ i ][ i + j ] = currNum++;
 
// do right side
for ( j = 1; j < sideLen; j++ )
( *spiralArrayPtr )[ i + j ][ dimension - 1 - i ] = currNum++;
 
// do bottom side
for ( j = sideLen - 2; j > -1; j-- )
( *spiralArrayPtr )[ dimension - 1 - i ][ i + j ] = currNum++;
 
// do left side
for ( j = sideLen - 2; j > 0; j-- )
( *spiralArrayPtr )[ i + j ][ i ] = currNum++;
 
sideLen -= 2;
}
 
return spiralArrayPtr;
}
 
void printSpiralArray( const auto_ptr< IntTable >& spiralArrayPtr )
{
size_t dimension = spiralArrayPtr->size();
 
int fieldWidth = static_cast< int >( floor( log10(
static_cast< double >( dimension * dimension - 1 ) ) ) ) + 2;
 
size_t col;
for ( size_t row = 0; row < dimension; row++ )
{
for ( col = 0; col < dimension; col++ )
cout << setw( fieldWidth ) << ( *spiralArrayPtr )[ row ][ col ];
cout << endl;
}
}
 
int main()
{
printSpiralArray( getSpiralArray( 5 ) );
}</lang>
 
C++ solution done properly:
<lang cpp>#include <vector>
#include <iostream>
using namespace std;
int main() {
const int n = 5;
const int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0};
int x = 0, y = -1, c = 0;
vector<vector<int>> m(n, vector<int>(n));
for (int i = 0, im = 0; i < n + n - 1; ++i, im = i % 4)
for (int j = 0, jlen = (n + n - i) / 2; j < jlen; ++j)
m[x += dx[im]][y += dy[im]] = ++c;
for (auto & r : m) {
for (auto & v : r)
cout << v << ' ';
cout << endl;
}
}</lang>
 
=={{header|C sharp|C#}}==
Solution based on the [[#J|J]] hints:
<langsyntaxhighlight lang="csharp">public int[,] Spiral(int n) {
int[,] result = new int[n, n];
 
Line 583 ⟶ 1,072:
Console.WriteLine();
}
}</langsyntaxhighlight>
 
Translated proper C++ solution:
<syntaxhighlight lang="csharp">
 
//generate spiral matrix for given N
int[,] CreateMatrix(int n){
int[] dx = {0, 1, 0, -1}, dy = {1, 0, -1, 0};
int x = 0, y = -1, c = 0;
int[,] m = new int[n,n];
for (int i = 0, im = 0; i < n + n - 1; ++i, im = i % 4)
for (int j = 0, jlen = (n + n - i) / 2; j < jlen; ++j)
m[x += dx[im],y += dy[im]] = ++c;
return n;
}
 
//print aligned matrix
void Print(int[,] matrix) {
var len = (int)Math.Ceiling(Math.Log10(m.GetLength(0) * m.GetLength(1)))+1;
for(var y = 0; y<m.GetLength(1); y++){
for(var x = 0; x<m.GetLength(0); x++){
Console.Write(m[y, x].ToString().PadRight(len, ' '));
}
Console.WriteLine();
}
}
</syntaxhighlight>
 
====Spiral Matrix without using an Array====
 
<langsyntaxhighlight lang="csharp">
using System;
using System.Collections.Generic;
Line 659 ⟶ 1,174:
}
}
</syntaxhighlight>
</lang>
{{Out}}
<langsyntaxhighlight lang="sh">INPUT:-
 
Enter order..
Line 691 ⟶ 1,206:
17 30 29 28 27 10
16 15 14 13 12 11
</syntaxhighlight>
</lang>
 
=={{header|C++}}==
<syntaxhighlight lang="cpp">#include <vector>
#include <memory> // for auto_ptr
#include <cmath> // for the ceil and log10 and floor functions
#include <iostream>
#include <iomanip> // for the setw function
 
using namespace std;
 
typedef vector< int > IntRow;
typedef vector< IntRow > IntTable;
 
auto_ptr< IntTable > getSpiralArray( int dimension )
{
auto_ptr< IntTable > spiralArrayPtr( new IntTable(
dimension, IntRow( dimension ) ) );
 
int numConcentricSquares = static_cast< int >( ceil(
static_cast< double >( dimension ) / 2.0 ) );
 
int j;
int sideLen = dimension;
int currNum = 0;
 
for ( int i = 0; i < numConcentricSquares; i++ )
{
// do top side
for ( j = 0; j < sideLen; j++ )
( *spiralArrayPtr )[ i ][ i + j ] = currNum++;
 
// do right side
for ( j = 1; j < sideLen; j++ )
( *spiralArrayPtr )[ i + j ][ dimension - 1 - i ] = currNum++;
 
// do bottom side
for ( j = sideLen - 2; j > -1; j-- )
( *spiralArrayPtr )[ dimension - 1 - i ][ i + j ] = currNum++;
 
// do left side
for ( j = sideLen - 2; j > 0; j-- )
( *spiralArrayPtr )[ i + j ][ i ] = currNum++;
 
sideLen -= 2;
}
 
return spiralArrayPtr;
}
 
void printSpiralArray( const auto_ptr< IntTable >& spiralArrayPtr )
{
size_t dimension = spiralArrayPtr->size();
 
int fieldWidth = static_cast< int >( floor( log10(
static_cast< double >( dimension * dimension - 1 ) ) ) ) + 2;
 
size_t col;
for ( size_t row = 0; row < dimension; row++ )
{
for ( col = 0; col < dimension; col++ )
cout << setw( fieldWidth ) << ( *spiralArrayPtr )[ row ][ col ];
cout << endl;
}
}
 
int main()
{
printSpiralArray( getSpiralArray( 5 ) );
}</syntaxhighlight>
 
C++ solution done properly:
<syntaxhighlight lang="cpp">#include <vector>
#include <iostream>
using namespace std;
int main() {
const int n = 5;
const int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0};
int x = 0, y = -1, c = 0;
vector<vector<int>> m(n, vector<int>(n));
for (int i = 0, im = 0; i < n + n - 1; ++i, im = i % 4)
for (int j = 0, jlen = (n + n - i) / 2; j < jlen; ++j)
m[x += dx[im]][y += dy[im]] = ++c;
for (auto & r : m) {
for (auto & v : r)
cout << v << ' ';
cout << endl;
}
}</syntaxhighlight>
 
=={{header|Clojure}}==
Based on the [[#J|J]] hints (almost as incomprehensible, maybe)
<langsyntaxhighlight lang="clojure">(defn spiral [n]
(let [cyc (cycle [1 n -1 (- n)])]
(->> (range (dec n) 0 -1)
(mapcat #(repeat 2 %))
(cons n)
#(mapcat #(repeat %2 %) cyc)
(reductions +)
(map vector (range 0 (* n n)))
Line 710 ⟶ 1,313:
true
(str " ~{~<~%~," (* n 3) ":;~2d ~>~}~%")
(spiral n)))</langsyntaxhighlight>
Recursive generation:
{{trans|Common Lisp}}
<syntaxhighlight lang="clojure">
(defn spiral-matrix [m n & [start]]
(let [row (list (map #(+ start %) (range m)))]
(if (= 1 n) row
(concat row (map reverse
(apply map list
(spiral-matrix (dec n) m (+ start m))))))))
 
(defn spiral [n m] (spiral-matrix n m 1))
</syntaxhighlight>
 
=={{header|CoffeeScript}}==
<langsyntaxhighlight lang="coffeescript">
# Let's say you want to arrange the first N-squared natural numbers
# in a spiral, where you fill in the numbers clockwise, starting from
Line 760 ⟶ 1,375:
console.log "\n----Spiral n=#{n}"
console.log spiral_matrix n
</syntaxhighlight>
</lang>
{{out}}
<syntaxhighlight lang="text">
> coffee spiral.coffee
 
Line 781 ⟶ 1,396:
[ 19, 36, 35, 34, 33, 32, 11 ],
[ 18, 17, 16, 15, 14, 13, 12 ] ]
</syntaxhighlight>
</lang>
 
 
=={{header|Common Lisp}}==
{{trans|Python}}
<langsyntaxhighlight lang="lisp">(defun spiral (rows columns)
(do ((N (* rows columns))
(spiral (make-array (list rows columns) :initial-element nil))
Line 803 ⟶ 1,417:
dy dx)
(setf x (+ x dx)
y (+ y dy)))))))</langsyntaxhighlight>
<pre>> (pprint (spiral 6 6))
 
Line 821 ⟶ 1,435:
(8 7 6))</pre>
Recursive generation:
<langsyntaxhighlight lang="lisp">(defun spiral (m n &optional (start 1))
(let ((row (list (loop for x from 0 to (1- m) collect (+ x start)))))
(if (= 1 n) row
Line 831 ⟶ 1,445:
;; test
(loop for row in (spiral 4 3) do
(format t "~{~4d~^~}~%" row))</langsyntaxhighlight>
 
=={{header|D}}==
<langsyntaxhighlight lang="d">void main() {
import std.stdio;
enum n = 5;
Line 853 ⟶ 1,467:
 
writefln("%(%(%2d %)\n%)", M);
}</langsyntaxhighlight>
{{out}}
<pre> 0 1 2 3 4
Line 861 ⟶ 1,475:
12 11 10 9 8</pre>
Using a generator for any rectangular array:
<langsyntaxhighlight lang="d">import std.stdio;
 
/// 2D spiral generator
Line 912 ⟶ 1,526:
foreach (r; spiralMatrix(9, 4))
writefln("%(%2d %)", r);
}</langsyntaxhighlight>
{{out}}
<pre> 0 1 2 3 4 5 6 7 8
Line 918 ⟶ 1,532:
20 35 34 33 32 31 30 29 10
19 18 17 16 15 14 13 12 11</pre>
 
=={{header|DCL}}==
<langsyntaxhighlight DCLlang="dcl">$ p1 = f$integer( p1 )
$ max = p1 * p1
$
Line 974 ⟶ 1,589:
$ endif
$ endif
$ return</langsyntaxhighlight>
{{out}}
<pre>$ @spiral_matrix 3
Line 988 ⟶ 1,603:
 
...</pre>
 
=={{header|Delphi}}==
{{works with|Delphi|6.0}}
{{libheader|SysUtils,StdCtrls, Windows}}
This code actually creates a matrix in memory and stores values in the matrix, instead of just simulating one by drawing the pattern. It can also create matrices of any size and the matrices don't have to be square. It works by creating a rectangle of the same size as the matrix. It enters the values in the matrix along circumference of the matrix. It then uses the Windows library routine "InflateRect" to decrease the size of the rectangle until the whole matrix is filled with spiraling values. Since a rectangle can be any size and doesn't have to be square, it works with any size matrix, including non-square matrices.
 
<syntaxhighlight lang="Delphi">
 
 
type TMatrix = array of array of double;
 
 
procedure DisplayMatrix(Memo: TMemo; Mat: TMatrix);
{Display specified matrix}
var X,Y: integer;
var S: string;
begin
S:='';
for Y:=0 to High(Mat[0]) do
begin
S:=S+'[';
for X:=0 to High(Mat) do
S:=S+Format('%4.0f',[Mat[X,Y]]);
S:=S+']'+#$0D#$0A;
end;
Memo.Lines.Add(S);
end;
 
 
procedure MakeSpiralMatrix(var Mat: TMatrix; SizeX,SizeY: integer);
{Create a spiral matrix of specified size}
var Inx: integer;
var R: TRect;
 
procedure DoRect(R: TRect; var Inx: integer);
{Create on turn of the spiral base on the rectangle}
var X,Y: integer;
begin
{Do top part of rectangle}
for X:=R.Left to R.Right do
begin
Mat[X,R.Top]:=Inx;
Inc(Inx);
end;
{Do Right part of rectangle}
for Y:=R.Top+1 to R.Bottom do
begin
Mat[R.Right,Y]:=Inx;
Inc(Inx);
end;
{Do bottom part of rectangle}
for X:= R.Right-1 downto R.Left do
begin
Mat[X,R.Bottom]:=Inx;
Inc(Inx);
end;
{Do left part of rectangle}
for Y:=R.Bottom-1 downto R.Top+1 do
begin
Mat[R.Left,Y]:=Inx;
Inc(Inx);
end;
end;
 
begin
{Set matrix size}
SetLength(Mat,SizeX,SizeY);
{create matching rectangle}
R:=Rect(0,0,SizeX-1,SizeY-1);
Inx:=0;
{draw and deflate rectangle until spiral is done}
while (R.Left<=R.Right) and (R.Top<=R.Bottom) do
begin
DoRect(R,Inx);
InflateRect(R,-1,-1);
end;
end;
 
 
 
procedure SpiralMatrix(Memo: TMemo);
{Display spiral matrix}
var Mat: TMatrix;
begin
Memo.Lines.Add('5x5 Matrix');
MakeSpiralMatrix(Mat,5,5);
DisplayMatrix(Memo,Mat);
 
Memo.Lines.Add('8x8 Matrix');
MakeSpiralMatrix(Mat,8,8);
DisplayMatrix(Memo,Mat);
 
Memo.Lines.Add('14x8 Matrix');
MakeSpiralMatrix(Mat,14,8);
DisplayMatrix(Memo,Mat);
end;
</syntaxhighlight>
{{out}}
<pre>
5x5 Matrix
[ 0 1 2 3 4]
[ 15 16 17 18 5]
[ 14 23 24 19 6]
[ 13 22 21 20 7]
[ 12 11 10 9 8]
 
8x8 Matrix
[ 0 1 2 3 4 5 6 7]
[ 27 28 29 30 31 32 33 8]
[ 26 47 48 49 50 51 34 9]
[ 25 46 59 60 61 52 35 10]
[ 24 45 58 63 62 53 36 11]
[ 23 44 57 56 55 54 37 12]
[ 22 43 42 41 40 39 38 13]
[ 21 20 19 18 17 16 15 14]
 
14x8 Matrix
[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13]
[ 39 40 41 42 43 44 45 46 47 48 49 50 51 14]
[ 38 71 72 73 74 75 76 77 78 79 80 81 52 15]
[ 37 70 95 96 97 98 99 100 101 102 103 82 53 16]
[ 36 69 94 111 110 109 108 107 106 105 104 83 54 17]
[ 35 68 93 92 91 90 89 88 87 86 85 84 55 18]
[ 34 67 66 65 64 63 62 61 60 59 58 57 56 19]
[ 33 32 31 30 29 28 27 26 25 24 23 22 21 20]
 
Elapsed Time: 11.242 ms.
 
</pre>
 
=={{header|E}}==
Line 993 ⟶ 1,737:
 
{{E 2D utilities}}
<langsyntaxhighlight lang="e">def spiral(size) {
def array := makeFlex2DArray(size, size)
var i := -1 # Counter of numbers to fill
Line 1,017 ⟶ 1,761:
return array
}</langsyntaxhighlight>
Example:
<langsyntaxhighlight lang="e">? print(spiral(5))
0 1 2 3 4
15 16 17 18 5
14 23 24 19 6
13 22 21 20 7
12 11 10 9 8</langsyntaxhighlight>
 
=={{header|EasyLang}}==
<syntaxhighlight>
proc mkspiral n . t[] .
subr side
for i to l
ind += d
t[ind] = cnt
cnt += 1
.
.
len t[] n * n
l = n
while cnt < len t[]
d = 1
side
l -= 1
d = n
side
d = -1
side
l -= 1
d = -n
side
.
.
n = 5
mkspiral n t[]
numfmt 0 3
for i to n * n
write t[i]
if i mod n = 0
print ""
.
.
</syntaxhighlight>
{{out}}
<pre>
0 1 2 3 4
15 16 17 18 5
14 23 24 19 6
13 22 21 20 7
12 11 10 9 8
</pre>
 
=={{header|Elixir}}==
{{trans|Ruby}}
<langsyntaxhighlight lang="elixir">defmodule RC do
def spiral_matrix(n) do
wide = length(to_char_list(n*n-1))
fmt = String.duplicate("~#{wide}w ", n) <> "~n"
runs = Enum.flat_map(n..1, &[&1,&1]) |> tl
delta = Stream.cycle([{0,1},{1,0},{0,-1},{-1,0}])
running(Enum.zip(runs,delta),0,-1,[])
|> Enum.with_index |> Enum.sort |> Enum.chunk(n)
|> Enum.each(fn row -> :io.format fmt, (for {_,i} <- row, do: i) end)
end
defp running([{run,{dx,dy}}|rest], x, y, track) do
new_track = Enum.reduce(1..run, track, fn i,acc -> [{x+i*dx, y+i*dy} | acc] end)
running(rest, x+run*dx, y+run*dy, new_track)
end
defp running([],_,_,track), do: track |> Enum.reverse
end
 
RC.spiral_matrix(5)</syntaxhighlight>
 
'''The other way'''
<syntaxhighlight lang="elixir">defmodule RC do
def spiral_matrix(n) do
wide = String.length(to_string(n*n-1))
right(n,n-1,0,[]) |> Enum.with_index |> Enum.sort |> Enum.with_index |>
fmt = EnumString.eachduplicate(fn "~#{{_,xwide}w ",i} -n) <> "~n"
right(n,n-1,0,[]) |> Enum.reverse |> Enum.with_index |> Enum.sort |> Enum.chunk(n) |>
:io.format("~2w ", [x])
Enum.each(fn row ->
if( rem(i+1,n)==0, do: IO.puts "")
:io.format fmt, (for {_,i} <- row, do: i)
end)
end
def right(n, side, i, coordinates) do
coorddown(n, =side, for j <-i, Enum.reduce(0..side, do:coordinates, fn j,acc -> [{i, i+j} | acc] end))
down(n,side,i,coordinates++coord)
end
def down(_, 0, _, coordinates), do: coordinates
def down(n, side, i, coordinates) do
coordleft(n, = for j <side-1, i, Enum.reduce(1..side, do:coordinates, fn j,acc -> [{i+j, n-1-i} | acc] end))
left(n,side-1,i,coordinates++coord)
end
def left(n, side, i, coordinates) do
coordup(n, =side, fori, j <- 0.Enum.reduce(side..0, do:coordinates, fn j,acc -> [{n-1-i, i+side-j} | acc] end))
up(n,side,i,coordinates++coord)
end
def up(_, 0, _, coordinates), do: coordinates
def up(n, side, i, coordinates) do
coordright(n, = for j <side-1, i+1, Enum..reduce(side..1, do:coordinates, fn j,acc -> [{i+side-j+1, i} | acc] end))
right(n,side-1,i+1,coordinates++coord)
end
end
 
RC.spiral_matrix(5)</langsyntaxhighlight>
 
'''Another way'''
<syntaxhighlight lang="elixir">defmodule RC do
def spiral_matrix(n) do
fmt = String.duplicate("~#{length(to_char_list(n*n-1))}w ", n) <> "~n"
Enum.flat_map(n..1, &[&1, &1])
|> tl
|> Enum.reduce({{0,-1},{0,1},[]}, fn run,{{x,y},{dx,dy},acc} ->
side = for i <- 1..run, do: {x+i*dx, y+i*dy}
{{x+run*dx, y+run*dy}, {dy, -dx}, acc++side}
end)
|> elem(2)
|> Enum.with_index
|> Enum.sort
|> Enum.map(fn {_,i} -> i end)
|> Enum.chunk(n)
|> Enum.each(fn row -> :io.format fmt, row end)
end
end
 
RC.spiral_matrix(5)</syntaxhighlight>
 
{{out}}
Line 1,072 ⟶ 1,899:
 
=={{header|Euphoria}}==
<langsyntaxhighlight Euphorialang="euphoria">function spiral(integer dimension)
integer side, curr, curr2
sequence s
Line 1,100 ⟶ 1,927:
end function
 
? spiral(5)</langsyntaxhighlight>
 
{{out}}
Line 1,110 ⟶ 1,937:
{12,11,10,9,8}
}
 
=={{header|F_Sharp|F#}}==
No fancy schmancy elegance here, just putting the numbers in the right place (though I commend the elegance)...
<syntaxhighlight lang="fsharp">let Spiral n =
let sq = Array2D.create n n 0 // Set up an output array
let nCur = ref -1 // Current value being inserted
let NextN() = nCur := (!nCur+1) ; !nCur // Inc current value and return new value
let Frame inset = // Create the "frame" at an offset from the outside
let rangeF = [inset..(n - inset - 2)] // Range we use going forward
let rangeR = [(n - inset - 1)..(-1)..(inset + 1)] // Range we use going backward
rangeF |> Seq.iter (fun i -> sq.[inset,i] <- NextN()) // Top of frame
rangeF |> Seq.iter (fun i -> sq.[i,n-inset-1] <- NextN()) // Right side of frame
rangeR |> Seq.iter (fun i -> sq.[n-inset-1,i] <- NextN()) // Bottom of frame
rangeR |> Seq.iter (fun i -> sq.[i,inset] <- NextN()) // Left side of frame
[0..(n/2 - 1)] |> Seq.iter (fun i -> Frame i) // Fill in all frames
if n &&& 1 = 1 then sq.[n/2,n/2] <- n*n - 1 // If n is odd, fill in the last single value
sq // Return our output array</syntaxhighlight>
 
=={{header|Factor}}==
This is an implementation of Joey Tuttle's method for computing a spiral directly as a list and then reshaping it into a matrix, as described in the [http://rosettacode.org/wiki/Spiral_matrix#J J entry]. To summarize, we construct a list with <code>n*n</code> elements by following some simple rules, then take its cumulative sum, and finally its inverse permutation (or grade in J parlance). This gives us a list which can be reshaped to the final matrix.
<syntaxhighlight lang="factor">USING: arrays grouping io kernel math math.combinatorics
math.ranges math.statistics prettyprint sequences
sequences.repeating ;
IN: rosetta-code.spiral-matrix
 
: counts ( n -- seq ) 1 [a,b] 2 repeat rest ;
 
: vals ( n -- seq )
[ 1 swap 2dup [ neg ] bi@ 4array ] [ 2 * 1 - cycle ] bi ;
 
: evJKT2 ( n -- seq )
[ counts ] [ vals ] bi [ <array> ] 2map concat ;
 
: spiral ( n -- matrix )
[ evJKT2 cum-sum inverse-permutation ] [ group ] bi ;
 
: spiral-demo ( -- ) 5 9 [ spiral simple-table. nl ] bi@ ;
 
MAIN: spiral-demo</syntaxhighlight>
{{out}}
<pre>
0 1 2 3 4
15 16 17 18 5
14 23 24 19 6
13 22 21 20 7
12 11 10 9 8
 
0 1 2 3 4 5 6 7 8
31 32 33 34 35 36 37 38 9
30 55 56 57 58 59 60 39 10
29 54 71 72 73 74 61 40 11
28 53 70 79 80 75 62 41 12
27 52 69 78 77 76 63 42 13
26 51 68 67 66 65 64 43 14
25 50 49 48 47 46 45 44 15
24 23 22 21 20 19 18 17 16
</pre>
 
=={{header|Fortran}}==
{{works with|Fortran|90 and later}}
<langsyntaxhighlight lang="fortran">PROGRAM SPIRAL
 
IMPLICIT NONE
Line 1,161 ⟶ 2,045:
END DO
 
END PROGRAM SPIRAL</langsyntaxhighlight>
 
=={{header|F_Sharp|F#FreeBASIC}}==
<syntaxhighlight lang="freebasic">' FB 1.05.0 Win64
No fancy schmancy elegance here, just putting the numbers in the right place (though I commend the elegance)...
 
<lang fsharp>let Spiral n =
Enum Direction
let sq = Array2D.create n n 0 // Set up an output array
across
let nCur = ref -1 // Current value being inserted
down
let NextN() = nCur := (!nCur+1) ; !nCur // Inc current value and return new value
back
let Frame inset = // Create the "frame" at an offset from the outside
up
let rangeF = [inset..(n - inset - 2)] // Range we use going forward
End Enum
let rangeR = [(n - inset - 1)..(-1)..(inset + 1)] // Range we use going backward
rangeF |> Seq.iter (fun i -> sq.[inset,i] <- NextN()) // Top of frame
Dim As Integer n
rangeF |> Seq.iter (fun i -> sq.[i,n-inset-1] <- NextN()) // Right side of frame
 
rangeR |> Seq.iter (fun i -> sq.[n-inset-1,i] <- NextN()) // Bottom of frame
Do
rangeR |> Seq.iter (fun i -> sq.[i,inset] <- NextN()) // Left side of frame
Input "Enter size of matrix "; n
[0..(n/2 - 1)] |> Seq.iter (fun i -> Frame i) // Fill in all frames
Loop Until n > 0
if n &&& 1 = 1 then sq.[n/2,n/2] <- n*n - 1 // If n is odd, fill in the last single value
 
sq // Return our output array</lang>
Dim spiral(1 To n, 1 To n) As Integer '' all zero by default
 
' enter the numbers 0 to (n^2 - 1) spirally in the matrix
 
Dim As Integer row = 1, col = 1, lowRow = 1, highRow = n, lowCol = 1, highCol = n
Dim d As Direction = across
 
For i As Integer = 0 To (n * n - 1)
spiral(row, col) = i
Select Case d
Case across
col += 1
If col > highCol Then
col = highCol
row += 1
d = down
End if
Case down
row += 1
If row > highRow Then
row = highRow
col -= 1
d = back
End if
Case back
col -= 1
If col < lowCol Then
col = lowCol
row -= 1
d = up
lowRow += 1
End If
Case up
row -= 1
If row < lowRow Then
row = lowRow
col += 1
d = across
highRow -= 1
lowCol += 1
highCol -= 1
End If
End Select
Next
 
' print spiral matrix if n < 20
Print
If n < 20 Then
For i As Integer = 1 To n
For j As Integer = 1 To n
Print Using "####"; spiral(i, j);
Next j
Print
Next i
Else
Print "Matrix is too big to display on 80 column console"
End If
 
Print
Print "Press any key to quit"
Sleep</syntaxhighlight>
 
{{out}}
<pre>
Enter size of matrix ? 5
 
0 1 2 3 4
15 16 17 18 5
14 23 24 19 6
13 22 21 20 7
12 11 10 9 8
</pre>
 
=={{header|GAP}}==
<langsyntaxhighlight lang="gap"># Spiral matrix with numbers 1 .. n<sup>2</sup>, more natural in GAP
SpiralMatrix := function(n)
local i, j, k, di, dj, p, vi, vj, imin, imax, jmin, jmax;
Line 1,227 ⟶ 2,183:
# [ 15, 24, 25, 20, 7 ],
# [ 14, 23, 22, 21, 8 ],
# [ 13, 12, 11, 10, 9 ] ]</langsyntaxhighlight>
 
=={{header|Go}}==
<langsyntaxhighlight lang="go">package main
 
import (
Line 1,287 ⟶ 2,243:
}
}
}</langsyntaxhighlight>
 
=={{header|Groovy}}==
Naive "path-walking" solution:
<langsyntaxhighlight lang="groovy">enum Direction {
East([0,1]), South([1,0]), West([0,-1]), North([-1,0]);
private static _n
Line 1,344 ⟶ 2,300:
}
M
}</langsyntaxhighlight>
Test:
<langsyntaxhighlight lang="groovy">(1..10).each { n ->
spiralMatrix(n).each { row ->
row.each { printf "%5d", it }
Line 1,352 ⟶ 2,308:
}
println ()
}</langsyntaxhighlight>
{{out}}
<pre style="height:30ex;overflow:scroll;"> 0
Line 1,421 ⟶ 2,377:
=={{header|Haskell}}==
Solution based on the [[#J|J]] hints:
<langsyntaxhighlight lang="haskell">import Data.List
import Control.Monad
grade xs = map snd. sort $ zip xs [0..]
Line 1,429 ⟶ 2,385:
spiral n = reshape n . grade. scanl1 (+). concat $ zipWith replicate (counts n) (values n)
displayRow = putStrLn . intercalate " " . map show
main = mapM displayRow $ spiral 5</langsyntaxhighlight>
 
An alternative, point-free solution based on the same J source.
 
<langsyntaxhighlight lang="haskell">import Data.List
import Control.Applicative
counts = tail . reverse . concat . map (replicate 2) . enumFromTo 1
Line 1,441 ⟶ 2,397:
parts = (<*>) take $ (.) <$> (map . take) <*> (iterate . drop) <*> copies
disp = (>> return ()) . mapM (putStrLn . intercalate " " . map show) . parts
main = disp 5</langsyntaxhighlight>
 
Another alternative:
<langsyntaxhighlight lang="haskell">import Data.List (transpose)
import Text.Printf (printf)
 
-- spiral is the first row plus a smaller spiral rotated 90 deg
spiral 0 _ _ = [[]]
spiral h w s = [[s .. s+w-1]] ++: rot90 (spiral w (h-1) (s+w))
where rot90 = (map reverse).transpose
 
-- this is sort of hideous, someone may want to fix it
main = mapM_ (\row->mapM_ ((printf "%4d").toInteger) row >> putStrLn "") (spiral 10 9 1)</langsyntaxhighlight>
 
 
Or less ambitiously,
{{Trans|AppleScript}}
<syntaxhighlight lang="haskell">import Data.List (intercalate, transpose)
 
---------------------- SPIRAL MATRIX ---------------------
spiral :: Int -> [[Int]]
spiral n = go n n 0
where
go rows cols x
| 0 < rows =
[x .. pred cols + x] :
fmap
reverse
(transpose $ go cols (pred rows) (x + cols))
| otherwise = [[]]
 
 
--------------------------- TEST -------------------------
main :: IO ()
main = putStrLn $ wikiTable $ spiral 5
 
 
--------------------- TABLE FORMATTING -------------------
wikiTable :: Show a => [[a]] -> String
wikiTable =
concat
. ("{| class=\"wikitable\" style=\"text-align: right;" :)
. ("width:12em;height:12em;table-layout:fixed;\"\n|-\n" :)
. return
. (<> "\n|}")
. intercalate "\n|-\n"
. fmap (('|' :) . (' ' :) . intercalate " || " . fmap show)</syntaxhighlight>
{{Out}}
{| class="wikitable" style="text-align: right;width:12em;height:12em;table-layout:fixed;"|-
| 0 || 1 || 2 || 3 || 4
|-
| 15 || 16 || 17 || 18 || 5
|-
| 14 || 23 || 24 || 19 || 6
|-
| 13 || 22 || 21 || 20 || 7
|-
| 12 || 11 || 10 || 9 || 8
|}
 
=={{header|Icon}} and {{header|Unicon}}==
At first I looked at keeping the filling of the matrix on track using /M[r,c] which fails when out of bounds or if the cell is null, but then I noticed the progression of the row and column increments from corner to corner reminded me of sines and cosines. I'm not sure if the use of a trigonometric function counts as elegance, perversity, or both. The generator could be easily modified to start at an arbitrary corner. Or count down to produce and evolute.
<langsyntaxhighlight Iconlang="icon">procedure main(A) # spiral matrix
N := 0 < integer(\A[1]|5) # N=1... (dfeault 5)
WriteMatrix(SpiralMatrix(N))
Line 1,484 ⟶ 2,486:
}
return M
end</langsyntaxhighlight>
 
{{out}}
Line 1,492 ⟶ 2,494:
13 22 21 20 7
12 11 10 9 8</pre>
 
=={{header|IS-BASIC}}==
<syntaxhighlight lang="is-basic">100 PROGRAM "SpiralMa.bas"
110 TEXT 80
120 INPUT PROMPT "Enter size of matrix (max. 10): ":N
130 NUMERIC A(1 TO N,1 TO N)
140 CALL INIT(A)
150 CALL WRITE(A)
160 DEF INIT(REF T)
170 LET BCOL,BROW,COL,ROW=1:LET TCOL,TROW=N:LET DIR=0
180 FOR I=0 TO N^2-1
190 LET T(COL,ROW)=I
200 SELECT CASE DIR
210 CASE 0
220 IF ROW<TROW THEN
230 LET ROW=ROW+1
240 ELSE
250 LET DIR=1:LET COL=COL+1:LET BCOL=BCOL+1
260 END IF
270 CASE 1
280 IF COL<TCOL THEN
290 LET COL=COL+1
300 ELSE
310 LET DIR=2:LET ROW=ROW-1:LET TROW=TROW-1
320 END IF
330 CASE 2
340 IF ROW>BROW THEN
350 LET ROW=ROW-1
360 ELSE
370 LET DIR=3:LET COL=COL-1:LET TCOL=TCOL-1
380 END IF
390 CASE 3
400 IF COL>BCOL THEN
410 LET COL=COL-1
420 ELSE
430 LET DIR=0:LET ROW=ROW+1:LET BROW=BROW+1
440 END IF
450 END SELECT
460 NEXT
470 END DEF
480 DEF WRITE(REF T)
490 FOR I=LBOUND(T,1) TO UBOUND(T,1)
500 FOR J=LBOUND(T,2) TO UBOUND(T,2)
510 PRINT USING " ##":T(I,J);
520 NEXT
530 PRINT
540 NEXT
550 END DEF</syntaxhighlight>
 
=={{header|J}}==
This function is the result of
some [http://www.jsoftware.com/papers/play132.htm beautiful insights]:
<langsyntaxhighlight lang="j">spiral =: ,~ $ [: /: }.@(2 # >:@i.@-) +/\@# <:@+: $ (, -)@(1&,)
 
spiral 5
Line 1,503 ⟶ 2,553:
14 23 24 19 6
13 22 21 20 7
12 11 10 9 8</langsyntaxhighlight>
Would you like [[Talk:Spiral#J|some hints]] that will allow you to reimplement it in another language?
 
Line 1,511 ⟶ 2,561:
{{trans|C++}}
{{works with|Java|1.5+}}
<langsyntaxhighlight lang="java5">public class Blah {
 
public static void main(String[] args) {
Line 1,561 ⟶ 2,611:
}
}
}</langsyntaxhighlight>
{{out}}
<pre> 0 1 2 3 4
Line 1,573 ⟶ 2,623:
===Imperative===
 
<langsyntaxhighlight lang="javascript">spiralArray = function (edge) {
var arr = Array(edge),
x = 0, y = edge,
Line 1,594 ⟶ 2,644:
arr = spiralArray(edge = 5);
for (y= 0; y < edge; y++) console.log(arr[y].join(" "));
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,603 ⟶ 2,653:
12 11 10 9 8</pre>
 
===Functional (ES5)===
 
====ES5====
 
Translating one of the Haskell versions:
 
<langsyntaxhighlight JavaScriptlang="javascript">(function (n) {
 
// Spiral: the first row plus a smaller spiral rotated 90 degrees clockwise
Line 1,622 ⟶ 2,674:
// rows and columns transposed (for 90 degree rotation)
function transpose(lst) {
return lst.length > 1 ? lst[0].map(function (_, col) {
functionreturn lst.map(_,function col(row) {
return lst.map(function (row) {[col];
return row[col]});
}) : })lst;
}
) : lst;
}
 
// elements in reverse order (for 90 degree rotation)
function reverse(lst) {
return lst.length > 1 ? lst.reduceRight(function (acc, x) {
functionreturn acc.concat(acc, x) {;
}, []) : return acc.concat(x)lst;
}, []
) : lst;
}
 
// [m..n]
function range(m, n) {
return Array.apply(null, Array(n - m + 1)).map(function (x, i) {
functionreturn (x,m i)+ {i;
return m + i});
}
);
}
 
// TESTING
var lstSpiral = spiral(n, n, 0);
 
 
// OUTPUT FORMATTING - JSON and wikiTable
function wikiTable(lstRows, blnHeaderRow, strStyle) {
return '{| class="wikitable" ' + (
Line 1,662 ⟶ 2,713:
}
 
return wikiTable([
wikiTable(
 
spiral(n, n, 0)lstSpiral,
 
false,
'text-align:center;width:12em;height:12em;table-layout:fixed;'
);,
JSON.stringify(lstSpiral)
].join('\n\n');
 
})(5);</langsyntaxhighlight>
 
Output:
Line 1,686 ⟶ 2,741:
| 12 || 11 || 10 || 9 || 8
|}
 
<syntaxhighlight lang="javascript">[[0,1,2,3,4],[15,16,17,18,5],[14,23,24,19,6],[13,22,21,20,7],[12,11,10,9,8]]</syntaxhighlight>
 
 
====ES6====
{{Trans|Haskell}}
<syntaxhighlight lang="javascript">(() => {
"use strict";
 
// ------------------ SPIRAL MATRIX ------------------
 
// spiral :: Int -> [[Int]]
const spiral = n => {
const go = (rows, cols, start) =>
Boolean(rows) ? [
enumFromTo(start)(start + pred(cols)),
...transpose(
go(
cols,
pred(rows),
start + cols
)
).map(reverse)
] : [
[]
];
 
return go(n, n, 0);
};
 
 
// ---------------------- TEST -----------------------
// main :: () -> String
const main = () => {
const
n = 5,
cellWidth = 1 + `${pred(n ** 2)}`.length;
 
return unlines(
spiral(n).map(
row => (
row.map(x => `${x}`
.padStart(cellWidth, " "))
)
.join("")
)
);
};
 
 
// --------------------- GENERIC ---------------------
 
// enumFromTo :: Int -> Int -> [Int]
const enumFromTo = m =>
n => Array.from({
length: 1 + n - m
}, (_, i) => m + i);
 
 
// pred :: Enum a => a -> a
const pred = x => x - 1;
 
 
// reverse :: [a] -> [a]
const reverse = xs =>
"string" === typeof xs ? (
xs.split("").reverse()
.join("")
) : xs.slice(0).reverse();
 
 
// transpose :: [[a]] -> [[a]]
const transpose = rows =>
// The columns of the input transposed
// into new rows.
// Simpler version of transpose, assuming input
// rows of even length.
Boolean(rows.length) ? rows[0].map(
(_, i) => rows.flatMap(
v => v[i]
)
) : [];
 
 
// unlines :: [String] -> String
const unlines = xs =>
// A single string formed by the intercalation
// of a list of strings with the newline character.
xs.join("\n");
 
 
// MAIN ---
return main();
})();</syntaxhighlight>
{{Out}}
<pre> 0 1 2 3 4
15 16 17 18 5
14 23 24 19 6
13 22 21 20 7
12 11 10 9 8</pre>
 
=={{header|jq}}==
Line 1,694 ⟶ 2,849:
 
'''Infrastructure''':
<langsyntaxhighlight lang="jq"># Create an m x n matrix
def matrix(m; n; init):
if m == 0 then []
Line 1,719 ⟶ 2,874:
elif . == [0, 1] then [ 1, 0]
else error("invalid direction: \(.)")
end;</langsyntaxhighlight>
'''Create a spiral n by n matrix'''
<langsyntaxhighlight lang="jq">def spiral(n):
# we just placed m at i,j, and we are moving in the direction d
def _next(i; j; m; d):
Line 1,734 ⟶ 2,889:
 
# Example
spiral(5) | neatly(3)</langsyntaxhighlight>
{{Out}}
$ jq -n -r -f spiral.jq
Line 1,747 ⟶ 2,902:
 
'''Spiral Matrix Iterator'''
<syntaxhighlight lang="julia">
<lang Julia>
immutable Spiral
m::Int
Line 1,791 ⟶ 2,946:
return (s, sps)
end
</syntaxhighlight>
</lang>
 
'''Helper Functions'''
<syntaxhighlight lang="julia">
<lang Julia>
using Formatting
 
Line 1,819 ⟶ 2,974:
return s
end
</syntaxhighlight>
</lang>
 
'''Main'''
<syntaxhighlight lang="julia">
<lang Julia>
n = 5
println("The n = ", n, " spiral matrix:")
Line 1,849 ⟶ 3,004:
end
println(pretty(a))
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,873 ⟶ 3,028:
71 157 151 149 139 137 37
67 61 59 53 47 43 41
</pre>
 
=={{header|Kotlin}}==
{{trans|C#}}
<syntaxhighlight lang="scala">// version 1.1.3
 
typealias Vector = IntArray
typealias Matrix = Array<Vector>
 
fun spiralMatrix(n: Int): Matrix {
val result = Matrix(n) { Vector(n) }
var pos = 0
var count = n
var value = -n
var sum = -1
do {
value = -value / n
for (i in 0 until count) {
sum += value
result[sum / n][sum % n] = pos++
}
value *= n
count--
for (i in 0 until count) {
sum += value
result[sum / n][sum % n] = pos++
}
}
while (count > 0)
return result
}
 
fun printMatrix(m: Matrix) {
for (i in 0 until m.size) {
for (j in 0 until m.size) print("%2d ".format(m[i][j]))
println()
}
println()
}
 
fun main(args: Array<String>) {
printMatrix(spiralMatrix(5))
printMatrix(spiralMatrix(10))
}</syntaxhighlight>
 
{{out}}
<pre>
0 1 2 3 4
15 16 17 18 5
14 23 24 19 6
13 22 21 20 7
12 11 10 9 8
 
0 1 2 3 4 5 6 7 8 9
35 36 37 38 39 40 41 42 43 10
34 63 64 65 66 67 68 69 44 11
33 62 83 84 85 86 87 70 45 12
32 61 82 95 96 97 88 71 46 13
31 60 81 94 99 98 89 72 47 14
30 59 80 93 92 91 90 73 48 15
29 58 79 78 77 76 75 74 49 16
28 57 56 55 54 53 52 51 50 17
27 26 25 24 23 22 21 20 19 18
</pre>
 
=={{header|Liberty BASIC}}==
Extended to include automatic scaling of the display scale and font. See [http://www.diga.me.uk/spiralM5.gif spiralM5]
<langsyntaxhighlight lang="lb">nomainwin
 
UpperLeftX = 50
Line 1,952 ⟶ 3,170:
[quit]
close #w
end</langsyntaxhighlight>
 
=={{header|Lua}}==
===Original===
<lang lua>av, sn = math.abs, function(s) return s~=0 and s/av(s) or 0 end
<syntaxhighlight lang="lua">av, sn = math.abs, function(s) return s~=0 and s/av(s) or 0 end
function sindex(y, x) -- returns the value at (x, y) in a spiral that starts at 1 and goes outwards
if y == -x and y >= x then return (2*y+1)^2 end
Line 1,973 ⟶ 3,192:
end
 
for i,v in ipairs(spiralt(8)) do for j, u in ipairs(v) do io.write(u .. " ") end print() end</langsyntaxhighlight>
 
===Alternate===
If only the printed output is required, without intermediate array storage, then:
<syntaxhighlight lang="lua">local function printspiral(n)
local function z(x,y)
local m = math.min(x, y, n-1-x, n-1-y)
return x<y and (n-2*m-2)^2+(x-m)+(y-m) or (n-2*m)^2-(x-m)-(y-m)
end
for y = 1, n do
for x = 1, n do
io.write(string.format("%2d ", n^2-z(x-1,y-1)))
end
print()
end
end
printspiral(9)</syntaxhighlight>
If the intermediate array storage ''is'' required, then:
<syntaxhighlight lang="lua">local function makespiral(n)
local t, z = {}, function(x,y)
local m = math.min(x, y, n-1-x, n-1-y)
return x<y and (n-2*m-2)^2+(x-m)+(y-m) or (n-2*m)^2-(x-m)-(y-m)
end
for y = 1, n do t[y] = {}
for x = 1, n do t[y][x] = n^2-z(x-1,y-1) end
end
return t
end
local function printspiral(t)
for y = 1, #t do
for x = 1, #t[y] do
io.write(string.format("%2d ", t[y][x]))
end
print()
end
end
printspiral(makespiral(9))</syntaxhighlight>
{{out}}
(same for both)
<pre> 0 1 2 3 4 5 6 7 8
31 32 33 34 35 36 37 38 9
30 55 56 57 58 59 60 39 10
29 54 71 72 73 74 61 40 11
28 53 70 79 80 75 62 41 12
27 52 69 78 77 76 63 42 13
26 51 68 67 66 65 64 43 14
25 50 49 48 47 46 45 44 15
24 23 22 21 20 19 18 17 16</pre>
 
=={{header|Maple}}==
 
<syntaxhighlight lang="maple">
with(ArrayTools):
 
spiralArray := proc(size::integer)
local M, sideLength, count, i, j:
M := Matrix(size):
count := 0:
sideLength := size:
for i from 1 to ceil(sideLength / 2) do
for j from 1 to sideLength do
M[i,i + j - 1] := count++:
end:
for j from 1 to sideLength - 1 do
M[i + j, sideLength + i - 1] := count++:
end:
for j from 1 to sideLength - 1 do
M[i + sideLength - 1, sideLength - j + i - 1] := count++:
end:
for j from 1 to sideLength - 2 do
M[sideLength + i - j - 1, i] := count++
end:
sideLength -= 2:
end:
return M;
end proc:
 
spiralArray(5);
 
</syntaxhighlight>
{{out}}<pre>
[ 0 1 2 3 4]
[ ]
[15 16 17 18 5]
[ ]
[14 23 24 19 6]
[ ]
[13 22 21 20 7]
[ ]
[12 11 10 9 8]
 
</pre>
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
We split the task up in 2 functions, one that adds a 'ring' around a present matrix. And a function that adds rings to a 'core':
<langsyntaxhighlight Mathematicalang="mathematica">AddSquareRing[x_List/;Equal@@Dimensions[x] && Length[Dimensions[x]]==2]:=Module[{new=x,size,smallest},
size=Length[x];
smallest=x[[1,1]];
Line 1,992 ⟶ 3,302:
times=If[Mod[size,2]==0,size/2-1,(size-1)/2];
Nest[AddSquareRing,start,times]
]</langsyntaxhighlight>
Examples:
<langsyntaxhighlight Mathematicalang="mathematica">MakeSquareSpiral[2] // MatrixForm
MakeSquareSpiral[7] // MatrixForm</langsyntaxhighlight>
gives back:
<math>
Line 2,026 ⟶ 3,336:
<math>(-spiral(n))+n^2</math>
Then depending on if n is odd or even we use either an up/down or left/right mirror transformation.
<langsyntaxhighlight MATLABlang="matlab">function matrix = reverseSpiral(n)
matrix = (-spiral(n))+n^2;
Line 2,036 ⟶ 3,346:
end
end %reverseSpiral</langsyntaxhighlight>
Sample Usage:
<langsyntaxhighlight MATLABlang="matlab">>> reverseSpiral(5)
 
ans =
Line 2,046 ⟶ 3,356:
14 23 24 19 6
13 22 21 20 7
12 11 10 9 8</langsyntaxhighlight>
 
=={{header|Maxima}}==
<langsyntaxhighlight lang="maxima">spiral(n) := block([a, i, j, k, p, di, dj, vi, vj, imin, imax, jmin, jmax],
a: zeromatrix(n, n),
vi: [1, 0, -1, 0],
Line 2,088 ⟶ 3,398:
[15, 24, 25, 20, 7],
[14, 23, 22, 21, 8],
[13, 12, 11, 10, 9]) */</langsyntaxhighlight>
 
=={{header|MiniZinc}}==
<syntaxhighlight lang="minizinc">
%Spiral Matrix. Nigel Galloway, February 3rd., 2020
int: Size;
array [1..Size,1..Size] of var 1..Size*Size: spiral;
constraint spiral[1,1..]=1..Size;
constraint forall(n in 2..(Size+1) div 2)(forall(g in n..Size+1-n)(spiral[n,g]=spiral[n,g-1]+1));
constraint forall(n in 1..(Size+1) div 2)(forall(g in n+1..Size+1-n)(spiral[g,Size-n+1]=spiral[g-1,Size-n+1]+1));
constraint forall(n in 1..Size div 2)(forall(g in n..Size-n)(spiral[Size-n+1,g]=spiral[Size-n+1,g+1]+1)) /\ forall(n in 1..Size div 2)(forall(g in n+1..Size-n)(spiral[g,n]=spiral[g+1,n]+1));
output [show2d(spiral)];
</syntaxhighlight>
{{out}}
<pre>
minizinc -DSize= spiral.mzn
 
[| 1, 2, 3, 4 |
12, 13, 14, 5 |
11, 16, 15, 6 |
10, 9, 8, 7 |]
----------
 
minizinc -DSize=5 zigzag.mzn
 
[| 1, 2, 3, 4, 5 |
16, 17, 18, 19, 6 |
15, 24, 25, 20, 7 |
14, 23, 22, 21, 8 |
13, 12, 11, 10, 9 |]
----------
 
minizinc -DSize=6 zigzag.mzn
 
[| 1, 2, 3, 4, 5, 6 |
20, 21, 22, 23, 24, 7 |
19, 32, 33, 34, 25, 8 |
18, 31, 36, 35, 26, 9 |
17, 30, 29, 28, 27, 10 |
16, 15, 14, 13, 12, 11 |]
----------
</pre>
 
=={{header|NetRexx}}==
{{Trans|ooRexx}}
<langsyntaxhighlight NetRexxlang="netrexx">/* NetRexx */
options replace format comments java crossref symbols binary
 
Line 2,184 ⟶ 3,535:
return maxNum
 
</syntaxhighlight>
</lang>
 
{{out}}
Line 2,205 ⟶ 3,556:
 
=={{header|Nim}}==
<langsyntaxhighlight lang="nim">import sequtils, strutils
 
type Pos = tuple[x, y: int]
 
proc newSeqWith[T](len: int, init: T): seq[T] =
result = newSeq[T] len
for i in 0 .. <len:
result[i] = init
 
proc `^`*(base: int, exp: int): int =
var (base, exp) = (base, exp)
result = 1
 
while exp != 0:
if (exp and 1) != 0:
result *= base
exp = exp shr 1
base *= base
 
proc `$`(m: seq[seq[int]]): string =
result = ""
for r in m:
let lg = result.len
for c in r:
result.addaddSep(" align($c", 2lg) & " "
result.add "\n"align($c, 2)
result.add '\n'
 
proc spiral(n: Positive): autoseq[seq[int]] =
result = newSeqWith(n, newSeqWith[int]repeat(n, -1, n))
var dx = 1
var dy, x, y = 0
for i in 0 .. < (n^2 * n):
result[y][x] = i
let (nx, ny) = (x+dx, y+dy)
if nx in 0 .. < n and ny in 0 .. < n and result[ny][nx] == -1:
x = nx
y = ny
Line 2,244 ⟶ 3,579:
swap dx, dy
dx = -dx
x = x += dx
y = y += dy
 
echo spiral(5)</langsyntaxhighlight>
{{out}}
<pre> 0 1 2 3 4
Line 2,256 ⟶ 3,591:
 
=={{header|OCaml}}==
<langsyntaxhighlight lang="ocaml">let next_dir = function
| 1, 0 -> 0, -1
| 0, 1 -> 1, 0
Line 2,294 ⟶ 3,629:
print_newline())
 
let () = print(spiral 5)</langsyntaxhighlight>
 
Another implementation:
<langsyntaxhighlight lang="ocaml">let spiral n =
let ar = Array.make_matrix n n (-1) in
let out i = i < 0 || i >= n in
Line 2,313 ⟶ 3,648:
Array.iter (fun v -> Array.iter (Printf.printf " %2d") v; print_newline())
 
let _ = show (spiral 5)</langsyntaxhighlight>
 
=={{header|Octave}}==
{{trans|Stata}}
The function <code>make_spiral</code> (and helper functions) are modelled after the J solution.
<langsyntaxhighlight lang="octave">function rsa = runsumspiral(vn)
for ia = 1:numelones(vn*n, 1);
u = rs-(i) = sumn) * (v = ones(n, 1:i));
for k = n-1:-1:1
j = 1:k;
a(j+i) = u(j) = -u(j);
a(j+(i+k)) = v(j) = -v(j);
i += 2*k;
endfor
a(cumsum(a)) = 1:n*n;
a = reshape(a, n, n)'-1;
endfunction
 
>> spiral(5)
function g = grade(v)
ans =
for i = 1:numel(v)
g(v(i)+1) = i-1;
endfor
endfunction
 
0 1 2 3 4
function spiral = make_spiral(spirald)
15 16 17 18 5
series = ones(1,spirald^2);
14 23 24 19 6
l = spirald-1; p = spirald+1;
13 22 21 20 7
s = 1;
12 11 10 9 8</syntaxhighlight>
while(l>0)
series(p:p+l-1) *= spirald*s;
series(p+l:p+l*2-1) *= -s;
p += l*2;
l--; s *= -1;
endwhile
series(1) = 0;
spiral = reshape(grade(runsum(series)), spirald, spirald)';
endfunction
 
make_spiral(5)</lang>
 
=={{header|Opal}}==
{{incorrect|Opal|It is incomplete.}}
Recursive functional solution
<lang opal>IMPLEMENTATION Spiral
 
IMPORT Nat COMPLETELY
IMPORT Seq COMPLETELY
 
DATA matrix == node(x:nat, y:nat, val:nat)
 
FUN spiral: nat -> seq[matrix]
DEF spiral(size) == </lang>
 
=={{header|ooRexx}}==
<syntaxhighlight lang="oorexx">
<lang ooRexx>
call printArray generateArray(3)
say
Line 2,415 ⟶ 3,731:
say line
end
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,433 ⟶ 3,749:
| 12 11 10 9 8 |
</pre>
 
 
=={{header|Oz}}==
Simple, recursive solution:
<langsyntaxhighlight lang="oz">declare
fun {Spiral N}
%% create nested array
Line 2,478 ⟶ 3,793:
end
in
{Inspect {Spiral 5}}</langsyntaxhighlight>
 
=={{header|PARI/GP}}==
 
<syntaxhighlight lang="parigp">spiral(dim) = {
my (M = matrix(dim, dim), p = s = 1, q = i = 0);
for (n=1, dim,
for (b=1, dim-n+1, M[p,q+=s] = i; i++);
for (b=1, dim-n, M[p+=s,q] = i; i++);
s = -s;
);
M
}</syntaxhighlight>
 
Output:<pre>spiral(7)
 
[ 0 1 2 3 4 5 6]
 
[23 24 25 26 27 28 7]
 
[22 39 40 41 42 29 8]
 
[21 38 47 48 43 30 9]
 
[20 37 46 45 44 31 10]
 
[19 36 35 34 33 32 11]
 
[18 17 16 15 14 13 12]</pre>
 
=={{header|Pascal}}==
<langsyntaxhighlight lang="pascal">program Spiralmat;
type
tDir = (left,down,right,up);
Line 2,551 ⟶ 3,894:
end;
END.
</syntaxhighlight>
</lang>
{{out}}
<pre> 1
Line 2,566 ⟶ 3,909:
 
=={{header|Perl}}==
<langsyntaxhighlight lang="perl">sub spiral
{my ($n, $x, $y, $dx, $dy, @a) = (shift, 0, 0, 1, 0);
foreach (0 .. $n**2 - 1)
Line 2,586 ⟶ 3,929:
foreach (spiral 5)
{printf "%3d", $_ foreach @$_;
print "\n";}</langsyntaxhighlight>
 
=={{header|Perl 6Phix}}==
{{trans|Python}}
===Object-oriented Solution===
Simple is better.
Suppose we set up a Turtle class like this:
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang perl6>enum Dir < north northeast east southeast south southwest west northwest >;
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
my $debug = 0;
<span style="color: #004080;">integer</span> <span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">6</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">x</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">y</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">counter</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">len</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">dx</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">dy</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">fmt</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%%%dd"</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%d"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">*</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)))</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">m</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"??"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">),</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">*</span><span style="color: #000000;">n</span> <span style="color: #008080;">do</span> <span style="color: #000080;font-style:italic;">-- 2n runs..</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">len</span> <span style="color: #008080;">do</span> <span style="color: #000080;font-style:italic;">-- of a length...</span>
<span style="color: #000000;">x</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">dx</span>
<span style="color: #000000;">y</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">dy</span>
<span style="color: #000000;">m</span><span style="color: #0000FF;">[</span><span style="color: #000000;">x</span><span style="color: #0000FF;">][</span><span style="color: #000000;">y</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fmt</span><span style="color: #0000FF;">,</span><span style="color: #000000;">counter</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">counter</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #000000;">len</span> <span style="color: #0000FF;">-=</span> <span style="color: #7060A8;">odd</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- ..-1 every other </span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">dx</span><span style="color: #0000FF;">,</span><span style="color: #000000;">dy</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">dy</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">dx</span><span style="color: #0000FF;">}</span> <span style="color: #000080;font-style:italic;">-- in new direction</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">apply</span><span style="color: #0000FF;">(</span><span style="color: #000000;">m</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">),</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">)})</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
0 1 2 3 4 5
19 20 21 22 23 6
18 31 32 33 24 7
17 30 35 34 25 8
16 29 28 27 26 9
15 14 13 12 11 10
</pre>
 
=={{header|PicoLisp}}==
class Turtle {
This example uses 'grid' from "lib/simul.l", which maintains a two-dimensional structure and is normally used for simulations and board games.
has @.loc = 0,0;
<syntaxhighlight lang="picolisp">(load "@lib/simul.l")
has Dir $.dir = north;
 
(de spiral (N)
my @dv = [0,-1], [1,-1], [1,0], [1,1], [0,1], [-1,1], [-1,0], [-1,-1];
(prog1 (grid N N)
my @num-to-dir = Dir.invert.sort».value;
(let (Dir '(north east south west .) This 'a1)
my $points = +Dir;
(for Val (* N N)
(=: val Val)
(setq This
(or
(with ((car Dir) This)
(unless (: val) This) )
(with ((car (setq Dir (cdr Dir))) This)
(unless (: val) This) ) ) ) ) ) ) )
 
(mapc
my %world;
'((L)
my $maxegg;
(for This L (prin (align 3 (: val))))
my $range-x;
my $range-y; (prinl) )
(spiral 5) )</syntaxhighlight>
 
method turn-left ($angle = 90) { $!dir -= $angle / 45; $!dir %= $points; }
method turn-right($angle = 90) { $!dir += $angle / 45; $!dir %= $points; }
 
method lay-egg($egg) {
%world{~@!loc} = $egg;
$maxegg max= $egg;
$range-x minmax= @!loc[0];
$range-y minmax= @!loc[1];
}
 
method look($ahead = 1) {
my $there = @!loc »+« (@dv[$!dir] X* $ahead);
say "looking @num-to-dir[$!dir] to $there" if $debug;
%world{~$there};
}
 
method forward($ahead = 1) {
my $there = @!loc »+« (@dv[$!dir] X* $ahead);
@!loc = @($there);
say " moving @num-to-dir[$!dir] to @!loc[]" if $debug;
}
 
method showmap() {
my $form = "%{$maxegg.chars}s";
my $endx = $range-x.max;
for $range-y.list X $range-x.list -> $y, $x {
print (%world{"$x $y"} // '').fmt($form);
print $x == $endx ?? "\n" !! ' ';
}
}
}</lang>
Now we can build the spiral in the normal way from outside-in like this:
<lang perl6>sub MAIN($size as Int) {
my $t = Turtle.new(dir => east);
my $counter = 0;
$t.forward(-1);
for 0..^ $size -> $ {
$t.forward;
$t.lay-egg($counter++);
}
for $size-1 ... 1 -> $run {
$t.turn-right;
$t.forward, $t.lay-egg($counter++) for 0..^$run;
$t.turn-right;
$t.forward, $t.lay-egg($counter++) for 0..^$run;
}
$t.showmap;
}</lang>
Or we can build the spiral from inside-out like this:
<lang perl6>sub MAIN($size as Int) {
my $t = Turtle.new(dir => ($size %% 2 ?? south !! north));
my $counter = $size * $size;
while $counter {
$t.lay-egg(--$counter);
$t.turn-left;
$t.turn-right if $t.look;
$t.forward;
}
$t.showmap;
}</lang>
Note that with these "turtle graphics" we don't actually have to care about the coordinate system, since the <code>showmap</code> method can show whatever rectangle was modified by the turtle. So unlike the standard inside-out algorithm, we don't have to find the center of the matrix first.
===Procedural Solution===
<lang perl6>sub spiral_matrix ( $n ) {
my @sm;
my $len = $n;
my $pos = 0;
 
for ^($n/2).ceiling -> $i {
my $j = $i + 1;
my $e = $n - $j;
 
@sm[$i ][$i + $_] = $pos++ for ^( $len); # Top
@sm[$j + $_][$e ] = $pos++ for ^(--$len); # Right
@sm[$e ][$i + $_] = $pos++ for reverse ^( $len); # Bottom
@sm[$j + $_][$i ] = $pos++ for reverse ^(--$len); # Left
}
 
return @sm;
}
 
say .fmt('%3d') for spiral_matrix(5);</lang>
{{out}}
<pre> 0 1 2 3 4 4 5
15 16 17 18 19 56
14 23 15 24 25 19 20 67
13 14 23 22 21 20 78
13 12 11 10 9 8</pre>
 
=={{header|PL/I}}==
<langsyntaxhighlight lang="pli">/* Generates a square matrix containing the integers from 0 to N**2-1, */
/* where N is the length of one side of the square. */
/* Written 22 February 2010. */
Line 2,750 ⟶ 4,046:
end;
 
end;</langsyntaxhighlight>
 
=={{header|PicoLispPowerShell}}==
<syntaxhighlight lang="powershell">function Spiral-Matrix ( [int]$N )
This example uses 'grid' from "lib/simul.l", which maintains a two-dimensional structure and is normally used for simulations and board games.
{
<lang PicoLisp>(load "@lib/simul.l")
# Initialize variables
$X = 0
$Y = -1
$i = 0
$Sign = 1
# Intialize array
$A = New-Object 'int[,]' $N, $N
# Set top row
1..$N | ForEach { $Y += $Sign; $A[$X,$Y] = ++$i }
# For each remaining half spiral...
ForEach ( $M in ($N-1)..1 )
{
# Set the vertical quarter spiral
1..$M | ForEach { $X += $Sign; $A[$X,$Y] = ++$i }
# Curve the spiral
$Sign = -$Sign
# Set the horizontal quarter spiral
1..$M | ForEach { $Y += $Sign; $A[$X,$Y] = ++$i }
}
# Convert the array to text output
$Spiral = ForEach ( $X in 1..$N ) { ( 1..$N | ForEach { $A[($X-1),($_-1)] } ) -join "`t" }
return $Spiral
}
Spiral-Matrix 5
""
Spiral-Matrix 7</syntaxhighlight>
{{out}}
<pre>1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
 
1 2 3 4 5 6 7
(de spiral (N)
24 25 26 27 28 29 8
(prog1 (grid N N)
23 40 41 42 43 30 9
(let (Dir '(north east south west .) This 'a1)
22 39 48 49 44 31 10
(for Val (* N N)
21 38 47 46 45 32 11
(=: val Val)
20 37 36 35 34 33 12
(setq This
19 18 17 16 15 14 13</pre>
(or
 
(with ((car Dir) This)
=={{header|Prolog}}==
(unless (: val) This) )
<syntaxhighlight lang="prolog">
(with ((car (setq Dir (cdr Dir))) This)
% Prolog implementation: SWI-Prolog 7.2.3
(unless (: val) This) ) ) ) ) ) ) )
 
replace([_|T], 0, E, [E|T]) :- !.
(mapc
replace([H|T], N, E, Xs) :-
'((L)
succ(N1, N), replace(T, N1, E, Xs1), Xs = [H|Xs1].
(for This L (prin (align 3 (: val))))
 
(prinl) )
% True if Xs is the Original grid with the element at (X, Y) replaces by E.
(spiral 5) )</lang>
replace_in([H|T], (0, Y), E, Xs) :- replace(H, Y, E, NH), Xs = [NH|T], !.
replace_in([H|T], (X, Y), E, Xs) :-
succ(X1, X), replace_in(T, (X1, Y), E, Xs1), Xs = [H|Xs1].
 
% True, if E is the value at (X, Y) in Xs
get_in(Xs, (X, Y), E) :- nth0(X, Xs, L), nth0(Y, L, E).
 
create(N, Mx) :- % NxN grid full of nils
numlist(1, N, Ns),
findall(X, (member(_, Ns), X = nil), Ls),
findall(X, (member(_, Ns), X = Ls), Mx).
 
% Depending of the direction, returns two possible coordinates and directions
% (C,D) that will be used in case of a turn, and (A,B) otherwise.
ops(right, (X,Y), (A,B), (C,D), D1, D2) :-
A is X, B is Y+1, D1 = right, C is X+1, D is Y, D2 = down.
 
ops(left, (X,Y), (A,B), (C,D), D1, D2) :-
A is X, B is Y-1, D1 = left, C is X-1, D is Y, D2 = up.
 
ops(up, (X,Y), (A,B), (C,D), D1, D2) :-
A is X-1, B is Y, D1 = up, C is X, D is Y+1, D2 = right.
 
ops(down, (X,Y), (A,B), (C,D), D1, D2) :-
A is X+1, B is Y, D1 = down, C is X, D is Y-1, D2 = left.
 
% True if NCoor is the right coor in spiral shape. Returns a new direction also.
next(Dir, Mx, Coor, NCoor, NDir) :-
ops(Dir, Coor, C1, C2, D1, D2),
(get_in(Mx, C1, nil) -> NCoor = C1, NDir = D1
; NCoor = C2, NDir = D2).
 
% Returns an spiral with [H|Vs] elements called R, only work if the length of
% [H|Vs], is the square of the size of the grid.
spiralH(Dir, Mx, Coor, [H|Vs], R) :-
replace_in(Mx, Coor, H, NMx),
(Vs = [] -> R = NMx
; next(Dir, Mx, Coor, NCoor, NDir),
spiralH(NDir, NMx, NCoor, Vs, R)).
 
% True if Mx is the grid in spiral shape of the numbers from 0 to N*N-1.
spiral(N, Mx) :-
Sq is N*N-1, numlist(0, Sq, Ns),
create(N, EMx), spiralH(right, EMx, (0,0), Ns, Mx).
</syntaxhighlight>
{{out}}
<pre> 1 2 3 4 5
?- spiral(6,Mx), forall(member(X,Mx), writeln(X)).
16 17 18 19 6
[0,1,2,3,4,5]
15 24 25 20 7
[19,20,21,22,23,6]
14 23 22 21 8
[18,31,32,33,24,7]
13 12 11 10 9</pre>
[17,30,35,34,25,8]
[16,29,28,27,26,9]
[15,14,13,12,11,10]
</pre>
 
=={{header|PureBasic}}==
{{trans|Fortran}}
<langsyntaxhighlight PureBasiclang="purebasic">Procedure spiralMatrix(size = 1)
Protected i, x = -1, y, count = size, n
Dim a(size - 1,size - 1)
Line 2,838 ⟶ 4,223:
Input()
CloseConsole()
EndIf</langsyntaxhighlight>
{{out}}
<pre>Spiral: 2
Line 2,855 ⟶ 4,240:
 
=={{header|Python}}==
<langsyntaxhighlight lang="python">def spiral(n):
dx,dy = 1,0 # Starting increments
x,y = 0,0 # Starting location
Line 2,876 ⟶ 4,261:
print
 
printspiral(spiral(5))</langsyntaxhighlight>
{{out}}
<pre>
Line 2,887 ⟶ 4,272:
 
===Recursive Solution===
<langsyntaxhighlight lang="python">def spiral(n):
def spiral_part(x, y, n):
if x == -1 and y == 0:
Line 2,909 ⟶ 4,294:
 
for row in spiral(5):
print " ".join("%2s" % x for x in row)</langsyntaxhighlight>
Adding a cache for the ''spiral_part'' function it could be quite efficient.
 
 
Recursion by rotating the solution for rest of the square except the first row,
<langsyntaxhighlight lang="python">def rot_right(a):
return zip(*a[::-1])
 
Line 2,931 ⟶ 4,316:
 
for row in spiral(5):
print(''.join('%3i' % i for i in row))</langsyntaxhighlight>
 
 
Another way, based on preparing lists ahead
<langsyntaxhighlight lang="python">def spiral(n):
dat = [[None] * n for i in range(n)]
le = [[i + 1, i + 1] for i in reversed(range(n))]
Line 2,950 ⟶ 4,335:
 
for row in spiral(5): # calc spiral and print it
print ' '.join('%3s' % x for x in row)</langsyntaxhighlight>
 
===Functional SolutionSolutions===
{{works with|Python|2.6, 3.0}}
<langsyntaxhighlight lang="python">import itertools
 
concat = itertools.chain.from_iterable
Line 2,972 ⟶ 4,357:
 
for row in spiral(5):
print(' '.join('%3s' % x for x in row))</langsyntaxhighlight>
 
 
Or, as an alternative to generative mutation:
{{Works with|Python|3.7}}
{{Trans|Haskell}}
<syntaxhighlight lang="python">'''Spiral Matrix'''
 
 
# spiral :: Int -> [[Int]]
def spiral(n):
'''The rows of a spiral matrix of order N.
'''
def go(rows, cols, x):
return [range(x, x + cols)] + [
reversed(x) for x
in zip(*go(cols, rows - 1, x + cols))
] if 0 < rows else [[]]
return go(n, n, 0)
 
 
# ------------------------- TEST -------------------------
# main :: IO ()
def main():
'''Spiral matrix of order 5, in wiki table markup.
'''
print(
wikiTable(spiral(5))
)
 
 
# ---------------------- FORMATTING ----------------------
 
# wikiTable :: [[a]] -> String
def wikiTable(rows):
'''Wiki markup for a no-frills tabulation of rows.'''
return '{| class="wikitable" style="' + (
'width:12em;height:12em;table-layout:fixed;"|-\n'
) + '\n|-\n'.join(
'| ' + ' || '.join(
str(cell) for cell in row
)
for row in rows
) + '\n|}'
 
 
# MAIN ---
if __name__ == '__main__':
main()
</syntaxhighlight>
{| class="wikitable" style="width:12em;height:12em;table-layout:fixed;"|-
| 0 || 1 || 2 || 3 || 4
|-
| 15 || 16 || 17 || 18 || 5
|-
| 14 || 23 || 24 || 19 || 6
|-
| 13 || 22 || 21 || 20 || 7
|-
| 12 || 11 || 10 || 9 || 8
|}
 
=== Simple solution ===
<syntaxhighlight lang ="python">def spiral_matrix(n = 5):
dx, dy m = [[0,] 1,* 0,n -1],for [1,i 0,in -1, 0range(n)]
x, y dx, cdy = [0, 1, 0, -1], [1, 0, -1, 0]
m = [[0 for ix, iny, range(n)]c for= j0, in-1, range(n)]1
for i in range(n + n - 1):
for j in range((n + n - i) // 2):
x += dx[i % 4]
y += dy[i % 4]
m[x][y] = c
c += 1
return m
print('\n'.join([' '.join([str(v) for v in r]) for r in m]))</lang>
for i in spiral_matrix(5): print(*i)</syntaxhighlight>
{{out}}
<syntaxhighlight lang="text">1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9</syntaxhighlight>
 
=={{header|RQuackery}}==
{{trans|Octave}}
<lang R>runsum <- function(v) {
rs <- c()
for(i in 1:length(v)) {
rs <- c(rs, sum(v[1:i]))
}
rs
}
 
This task really lends itself to a turtle graphics metaphor.
grade <- function(v) {
g <- vector("numeric", length(v))
for(i in 1:length(v)) {
g[v[i]] <- i-1
}
g
}
 
<syntaxhighlight lang="quackery"> [ stack ] is stepcount ( --> s )
makespiral <- function(spirald) {
[ stack ] is position ( --> s )
series <- vector("numeric", spirald^2)
[ stack ] is heading ( --> s )
series[] <- 1
l <- spirald-1; p <- spirald+1
s <- 1
while(l > 0) {
series[p:(p+l-1)] <- series[p:(p+l-1)] * spirald*s
series[(p+l):(p+l*2-1)] <- -s*series[(p+l):(p+l*2-1)]
p <- p + l*2
l <- l - 1; s <- -s
}
matrix(grade(runsum(series)), spirald, spirald, byrow=TRUE)
[ heading take
}
behead join
heading put ] is right ( --> )
[ heading share 0 peek
unrot times
[ position share
stepcount share
unrot poke
over position tally
1 stepcount tally ]
nip ] is walk ( [ n --> [ )
 
[ dip [ temp put [] ]
temp share times
[ temp share split
dip
[ nested join ] ]
drop temp release ] is matrixify ( n [ --> [ )
 
[ 0 stepcount put ( set up... )
0 position put
' [ 1 ] over join
-1 join over negate join
heading put
0 over dup * of
over 1 - walk right ( turtle draws spiral )
over 1 - times
[ i 1+ walk right
i 1+ walk right ]
1 walk
matrixify ( ...tidy up )
heading release
position release
stepcount release ] is spiral ( n --> [ )
 
9 spiral
witheach
[ witheach
[ dup 10 < if sp echo sp ]
cr ]</syntaxhighlight>
 
{{out}}
 
<pre> 0 1 2 3 4 5 6 7 8
31 32 33 34 35 36 37 38 9
30 55 56 57 58 59 60 39 10
29 54 71 72 73 74 61 40 11
28 53 70 79 80 75 62 41 12
27 52 69 78 77 76 63 42 13
26 51 68 67 66 65 64 43 14
25 50 49 48 47 46 45 44 15
24 23 22 21 20 19 18 17 16</pre>
 
=={{header|R}}==
===Sequence Solution===
<syntaxhighlight lang="rsplus">spiral <- function(n) matrix(order(cumsum(rep(rep_len(c(1, n, -1, -n), 2 * n - 1), n - seq(2 * n - 1) %/% 2))), n, byrow = T) - 1
 
spiral(5)</syntaxhighlight>
{{out}}
<pre> [,1] [,2] [,3] [,4] [,5]
[1,] 0 1 2 3 4
[2,] 15 16 17 18 5
[3,] 14 23 24 19 6
[4,] 13 22 21 20 7
[5,] 12 11 10 9 8</pre>
 
print(makespiral(5))</lang>
===Recursive Solution===
<syntaxhighlight lang="rsplus">spiral_matrix <- function(n) {
<lang R>#more general function, v is assumed to be a vector
spiralv <- function(v) {
n <- sqrt(length(v))
if (n != floor(n))
if(n!=floor(n)) stop(simpleError("length of v should be a square of an integer"))
if(n==0) stop(simpleError("length of v should be a square of positivean lengthinteger"))
if (n ==1) M<-matrix(v,1,10)
stop("v should be of positive length")
else M<-rbind(v[1:n],cbind(spiralv(v[(2*n):(n^2)])[(n-1):1,(n-1):1],v[(n+1):(2*n-1)]))
if (n == 1)
M
m <- matrix(v, 1, 1)
}
else
#wrapper
m <- rbind(v[1:n], cbind(spiralv(v[(2 * n):(n^2)])[(n - 1):1, (n - 1):1], v[(n + 1):(2 * n - 1)]))
spiral<-function(n){spiralv(0:(n^2-1))}
m
#check:
}
spiral(5)</lang>
spiralv(1:(n^2))
}</syntaxhighlight>
 
===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.
<syntaxhighlight lang="rsplus">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 <- seq_len(neededLength)
switch(writingDirectionIndex,
writeRight(seq),
writeDown(seq),
writeRight(-seq),
writeDown(-seq))
if(writingDirectionIndex %% 2) neededLength <- neededLength - 1
max <- max(spiral)
firstNumToWrite <- max + 1
startPt <- which(max == spiral, arr.ind = TRUE)
}
spiral
}</syntaxhighlight>
 
=={{header|Racket}}==
<langsyntaxhighlight lang="racket">
#lang racket
(require math)
Line 3,062 ⟶ 4,589:
 
(vector->matrix 4 4 (spiral 4 4))
</syntaxhighlight>
</lang>
{{out}}
<langsyntaxhighlight lang="racket">
(mutable-array #[#[0 1 2 3] #[11 12 13 4] #[10 15 14 5] #[9 8 7 6]])
</syntaxhighlight>
</lang>
 
=={{header|Raku}}==
(formerly Perl 6)
===Object-oriented Solution===
Suppose we set up a Turtle class like this:
<syntaxhighlight lang="raku" line>class Turtle {
my @dv = [0,-1], [1,-1], [1,0], [1,1], [0,1], [-1,1], [-1,0], [-1,-1];
my $points = 8; # 'compass' points of neighbors on grid: north=0, northeast=1, east=2, etc.
 
has @.loc = 0,0;
has $.dir = 0;
has %.world;
has $.maxegg;
has $.range-x;
has $.range-y;
 
method turn-left ($angle = 90) { $!dir -= $angle / 45; $!dir %= $points; }
method turn-right($angle = 90) { $!dir += $angle / 45; $!dir %= $points; }
 
method lay-egg($egg) {
%!world{~@!loc} = $egg;
$!maxegg max= $egg;
$!range-x minmax= @!loc[0];
$!range-y minmax= @!loc[1];
}
 
method look($ahead = 1) {
my $there = @!loc »+« @dv[$!dir] »*» $ahead;
%!world{~$there};
}
 
method forward($ahead = 1) {
my $there = @!loc »+« @dv[$!dir] »*» $ahead;
@!loc = @($there);
}
 
method showmap() {
my $form = "%{$!maxegg.chars}s";
my $endx = $!range-x.max;
for $!range-y.list X $!range-x.list -> ($y, $x) {
print (%!world{"$x $y"} // '').fmt($form);
print $x == $endx ?? "\n" !! ' ';
}
}
}
 
# Now we can build the spiral in the normal way from outside-in like this:
 
sub MAIN(Int $size = 5) {
my $t = Turtle.new(dir => 2);
my $counter = 0;
$t.forward(-1);
for 0..^ $size -> $ {
$t.forward;
$t.lay-egg($counter++);
}
for $size-1 ... 1 -> $run {
$t.turn-right;
$t.forward, $t.lay-egg($counter++) for 0..^$run;
$t.turn-right;
$t.forward, $t.lay-egg($counter++) for 0..^$run;
}
$t.showmap;
}</syntaxhighlight>
 
Or we can build the spiral from inside-out like this:
 
<syntaxhighlight lang="raku" line>sub MAIN(Int $size = 5) {
my $t = Turtle.new(dir => ($size %% 2 ?? 4 !! 0));
my $counter = $size * $size;
while $counter {
$t.lay-egg(--$counter);
$t.turn-left;
$t.turn-right if $t.look;
$t.forward;
}
$t.showmap;
}</syntaxhighlight>
Note that with these "turtle graphics" we don't actually have to care about the coordinate system, since the <code>showmap</code> method can show whatever rectangle was modified by the turtle. So unlike the standard inside-out algorithm, we don't have to find the center of the matrix first.
 
===Procedural Solution===
<syntaxhighlight lang="raku" line>sub spiral_matrix ( $n ) {
my @sm;
my $len = $n;
my $pos = 0;
 
for ^($n/2).ceiling -> $i {
my $j = $i + 1;
my $e = $n - $j;
 
@sm[$i ][$i + $_] = $pos++ for ^( $len); # Top
@sm[$j + $_][$e ] = $pos++ for ^(--$len); # Right
@sm[$e ][$i + $_] = $pos++ for reverse ^( $len); # Bottom
@sm[$j + $_][$i ] = $pos++ for reverse ^(--$len); # Left
}
 
return @sm;
}
 
say .fmt('%3d') for spiral_matrix(5);</syntaxhighlight>
{{out}}
<pre> 0 1 2 3 4
15 16 17 18 5
14 23 24 19 6
13 22 21 20 7
12 11 10 9 8</pre>
 
=={{header|REXX}}==
Original logic borrowed (mostly) from the [[#Fortran|Fortran]] example.
===static column width===
<langsyntaxhighlight lang="rexx">/*REXX program displays a spiral in a square array (of any size). starting at START. */
parse arg size start . /*getobtain theoptional array sizearguments from the CL.*/
if size =='' then| size =5 ="," then size =5 /*NoNot argumentspecified? Then use the default.*/
totif start=size**2 ='' | start=="," then start=0 /*totalNot specified? # ofThen elementsuse inthe spiraldefault.*/
ktot=size**2; L=length(tot + start) /*Ktotal isnumber theof counterelements for thein spiral. */
rowk=1;size col=0; start=0 /*startK: at row 1,is colthe 0,counter for withthe 0spiral. */
row=1; col=0 /*start spiral at row 1, column 0. */
/*──────────────────────────────────────────────construct the spiral #s.*/
/* [↓] construct the numbered spiral. */
do n=start for k; col=col+1; @.col.row=n; end; if k==0 then exit
do n=0 for k; col=col + 1; @.col.row=n + start; end; if k==0 then /* [↑] build first row of spiral*/exit
do until n>=tot /*spiral matrix[↑] build the first row of spiral. */
do oneuntil n>=1tot to -1 by -2 until n>=tot; k=k-1 /*performspiral twicematrix.*/
do none=n1 forto k;-1 rowby -2 until n>=row+onetot; @.col.row k=n;k-1 end /*forperform the row···twice.*/
do n=n for k; col row=col-row + one; @.col.row=n + start; end /*for "the " colrow···*/
end /*one*/ do n=n for k; col=col - one; @.col.row=n + start; end /* " " /* ↑↓ direction.col···*/
end end /*until n≥totone*/ /* [↑] done with matrix spiral /* ↑↓ direction.*/
end /*until n≥tot*/ /* [↑] done with the matrix spiral. */
/*──────────────────────────────────────────────display spiral to screen*/
do row=1 for size; _= /*construct display[↓] row bydisplay spiral rowto the screen. */
do do colr=1 for size; _= right(@.1.r, L) /*construct adisplay line colrow by col row. */
do c=2 for size -1; _=_ right(@.colc.rowr, length(tot)L) /*construct a line for the display. */
end /*col*/ /* [↑] line has an extra leading blank.*/
say substr(_,2) /*SUBSTRdisplay ignoresa theline first(row) blankof the spiral. */
end /*row*/ /*stick a fork in it, we're all done. */</langsyntaxhighlight>
{{out}}|output|text=&nbsp; using the default array size of: &nbsp; '''5'''}}
<pre>
0 1 2 3 4
Line 3,101 ⟶ 4,734:
12 11 10 9 8
</pre>
{{out}}|output|text=&nbsp; using an array size of&nbsp; and &nbsp; start value of: &nbsp; '''3610''' &nbsp; '''-70000'''}}
<pre>
<pre style="height:30ex">
-70000 -69999 -69998 -69997 -69996 -69995 -69994 -69993 -69992 -69991
-69965 -69964 -69963 -69962 -69961 -69960 -69959 -69958 -69957 -69990
-69966 -69937 -69936 -69935 -69934 -69933 -69932 -69931 -69956 -69989
-69967 -69938 -69917 -69916 -69915 -69914 -69913 -69930 -69955 -69988
-69968 -69939 -69918 -69905 -69904 -69903 -69912 -69929 -69954 -69987
-69969 -69940 -69919 -69906 -69901 -69902 -69911 -69928 -69953 -69986
-69970 -69941 -69920 -69907 -69908 -69909 -69910 -69927 -69952 -69985
-69971 -69942 -69921 -69922 -69923 -69924 -69925 -69926 -69951 -69984
-69972 -69943 -69944 -69945 -69946 -69947 -69948 -69949 -69950 -69983
-69973 -69974 -69975 -69976 -69977 -69978 -69979 -69980 -69981 -69982
</pre>
{{out|output|text=&nbsp; (shown at <sup>3</sup>/<sub>4</sub> size) &nbsp; using an array size of: &nbsp; '''36'''
<b>
<pre style="font-size:75%">
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 36
Line 3,140 ⟶ 4,787:
105 104 103 102 101 100 99 98 97 96 95 94 93 92 91 90 89 88 87 86 85 84 83 82 81 80 79 78 77 76 75 74 73 72 71 70
</pre>
</b>
 
===minimum column width===
This REXX version automatically adjusts the width of the spiral matrix columns to minimize the area of the matrix display (so more elements may be shown on a display screen).
<langsyntaxhighlight lang="rexx">/*REXX program displays a spiral in a square array (of any size). starting at START. */
parse arg size start . /*getobtain theoptional array sizearguments from the CL.*/
if size =='' then| size =5 ="," then size =5 /*NoNot argumentspecified? Then use the default.*/
totif start=size**2 ='' | start=="," then start=0 /*totalNot specified? # ofThen elementsuse inthe spiraldefault.*/
ktot=size**2; L=length(tot + start) /*Ktotal isnumber theof counterelements for thein spiral. */
rowk=1;size col=0; start=0 /*startK: at row 1,is colthe 0,counter for withthe 0spiral. */
row=1; col=0 /*start spiral at row 1, column 0. */
/*──────────────────────────────────────────────construct the spiral #s.*/
/* [↓] construct the numbered spiral. */
do n=start for k; col=col+1; @.col.row=n; end; if k==0 then exit
do n=0 for k; col=col + 1; @.col.row=n + start; end; if k==0 then /* [↑] build first row of spiral*/exit
do until n>=tot /*spiral matrix[↑] build the first row of spiral. */
do oneuntil n>=1tot to -1 by -2 until n>=tot; k=k-1 /*performspiral twicematrix.*/
do none=n1 forto k;-1 rowby -2 until n>=row+onetot; @.col.row k=n;k - 1 end /*forperform the row···twice.*/
do n=n for k; col row=col-row + one; @.col.row=n + start; end /*for "the " colrow···*/
end /*one*/ do n=n for k; col=col - one; @.col.row=n + start; end /* " " /* ↑↓ direction.col···*/
end end /*until n≥totone*/ /* [↑] done with matrix spiral /* ↑↓ direction.*/
end /*until n≥tot*/ /* [↑] done with the matrix spiral. */
/*──────────────────────────────────────────────display spiral to screen*/
!.=0 /* [↓] display spiral to the screen. */
do twice=0 for 2; if \twice then !.=0 /*1st time? Find max col width.*/
do rowtwo=10 for size;2 _= /*construct1st displaytime? row byFind row.max column and width.*/
do col r=1 for size; x_=@.col.row /*construct adisplay line colrow by col row. */
if twice thendo _c=_1 for size; right(x,!=@.col)c.r /*construct a line forcolumn displayby column. */
if two then _=_ elseright(x, !.col=max(!.col,length(x)c) /*findconstruct a line for the display. width of column*/
end /*col*/ else !.c=max(!.c, length(x)) /*find [↓] the linemaximum haswidth anof extrathe blankcolumn.*/
end /*c*/ /* [↓] line has an extra leading blank*/
if twice then say substr(_,2) /*SUBSTR ignores the 1st blank. */
end if /*row*/ two then say substr(_, 2) /*stickthis aSUBSTR forkignores inthe it,first we'reblank. done*/
end end /*twicer*/</lang>
end /*two*/ /*stick a fork in it, we're all done. */</syntaxhighlight>
{{out}} using an array size of; &nbsp; '''36'''
{{out|output|text=&nbsp; (shown at <sup>3</sup>/<sub>4</sub> size) &nbsp; using an array size of: &nbsp; '''36'''
<pre style="height:30ex">
<b>
<pre style="font-size:75%">
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 36
Line 3,206 ⟶ 4,856:
106 239 238 237 236 235 234 233 232 231 230 229 228 227 226 225 224 223 222 221 220 219 218 217 216 215 214 213 212 211 210 209 208 207 206 69
105 104 103 102 101 100 99 98 97 96 95 94 93 92 91 90 89 88 87 86 85 84 83 82 81 80 79 78 77 76 75 74 73 72 71 70
</pre>
</b>
 
=={{header|Ring}}==
<syntaxhighlight lang="ring">
# Project : Spiral matrix
 
load "guilib.ring"
load "stdlib.ring"
new qapp
{
win1 = new qwidget() {
setwindowtitle("Spiral matrix")
setgeometry(100,100,600,400)
n = 5
result = newlist(n,n)
spiral = newlist(n,n)
k = 1
top = 1
bottom = n
left = 1
right = n
while (k <= n*n)
for i= left to right
result[top][i] = k
k = k + 1
next
top = top + 1
for i = top to bottom
result[i][right] = k
k = k + 1
next
right = right - 1
for i = right to left step -1
result[bottom][i] = k
k = k + 1
next
bottom = bottom - 1
for i = bottom to top step -1
result[i][left] = k
k = k + 1
next
left = left + 1
end
for m = 1 to n
for p = 1 to n
spiral[p][m] = new qpushbutton(win1) {
x = 150+m*40
y = 30 + p*40
setgeometry(x,y,40,40)
settext(string(result[m][p]))
}
next
next
show()
}
exec()
}
</syntaxhighlight>
Output:
 
[http://keptarhely.eu/view.php?file=20220218v00xuh6r2.jpeg Spiral matrix]
 
=={{header|RPL}}==
{{works with|RPL|HP48-R}}
« { 0 1 } → n step
« { 1 1 } n DUP 2 →LIST -1 CON <span style="color:grey">@ empty cell = -1</span>
1 n SQ '''FOR''' j
OVER j PUT
DUP2 SWAP step ADD
'''IF IFERR''' GET '''THEN''' DROP2 1 '''ELSE''' -1 ≠ '''END''' <span style="color:grey">@ if next step is out of border or an already written cell</span>
'''THEN''' step REVLIST { 1 -1 } * 'step' STO '''END''' <span style="color:grey">@ then turn right</span>
SWAP step ADD SWAP
'''NEXT'''
» » '<span style="color:blue">SPIRAL</span>' STO
 
5 <span style="color:blue">SPIRAL</span>
{{out}}
<pre>
1: [[1 2 3 4 5]
[16 17 18 19 6]
[15 24 25 20 7]
[14 23 22 21 8]
[13 12 11 10 9]]
</pre>
 
=={{header|Ruby}}==
{{trans|Python}}
<langsyntaxhighlight lang="ruby">def spiral(n)
spiral = Array.new(n) {Array.new(n, nil)} # n x n array of nils
runs = n.downto(0).each_cons(2).to_a.flatten # n==5; [5,4,4,3,3,2,2,1,1,0]
Line 3,227 ⟶ 4,961:
end
 
print_matrix spiral(5)</langsyntaxhighlight>
{{out}}
<pre>
Line 3,239 ⟶ 4,973:
The other way
{{trans|D}}
<langsyntaxhighlight lang="ruby">n = 5
m = Array.new(n){Array.new(n)}
pos, side = -1, n
Line 3,251 ⟶ 4,985:
 
fmt = "%#{(n*n-1).to_s.size}d " * n
puts m.map{|row| fmt % row}</langsyntaxhighlight>
 
Output as above.
Line 3,257 ⟶ 4,991:
 
It processes the Array which is for work without creating it.
<langsyntaxhighlight lang="ruby">def spiral_matrix(n)
x, y, dx, dy = -1, 0, 0, -1
fmt = "%#{(n*n-1).to_s.size}d " * n
Line 3,266 ⟶ 5,000:
end
 
spiral_matrix(5)</langsyntaxhighlight>
 
=={{header|Rust}}==
<syntaxhighlight lang="rust">const VECTORS: [(isize, isize); 4] = [(1, 0), (0, 1), (-1, 0), (0, -1)];
 
pub fn spiral_matrix(size: usize) -> Vec<Vec<u32>> {
let mut matrix = vec![vec![0; size]; size];
let mut movement = VECTORS.iter().cycle();
let (mut x, mut y, mut n) = (-1, 0, 1..);
 
for (move_x, move_y) in std::iter::once(size)
.chain((1..size).rev().flat_map(|n| std::iter::repeat(n).take(2)))
.flat_map(|steps| std::iter::repeat(movement.next().unwrap()).take(steps))
{
x += move_x;
y += move_y;
matrix[y as usize][x as usize] = n.next().unwrap();
}
 
matrix
}
 
fn main() {
for i in spiral_matrix(4).iter() {
for j in i.iter() {
print!("{:>2} ", j);
}
println!();
}
}</syntaxhighlight>
{{out}}
<pre>
0 1 2 3 4
15 16 17 18 5
14 23 24 19 6
13 22 21 20 7
12 11 10 9 8
</pre>
 
=={{header|Scala}}==
<langsyntaxhighlight lang="scala">class Folder(){
var dir = (1,0)
var pos = (-1,0)
Line 3,290 ⟶ 5,061:
folds.foreach {len => fold(seq.take(len),array); seq = seq.drop(len)}
array
}</langsyntaxhighlight>
Explanation: if you see the sequence of numbers to spiral around as a tape to fold around, you can see this pattern on the lenght of tape segment to fold in each step:
:<math>N,\ N-1,\ N-1,\ \ldots,\ 1,\ 1</math>
Line 3,301 ⟶ 5,072:
 
=={{header|Scilab}}==
{{trans|BBC BasicOctave}}
<syntaxhighlight lang="text">function a = spiral(n)
<lang>// Spiral Matrix
a = ones(n*n, 1)
n=10
mat v =zeros ones(n,n 1);
u = -n*v;
botcol=1; topcol=n
i = n
botrow=1; toprow=n
for k = n-1:-1:1
ndir=0; col=1; row=1;
j = 1:k
for i=0:n*n-1
mat u(row,colj) =i; -u(j)
if ndira(j+i) ==0 u(j)
v(j) = -v(j)
if col<topcol then col=col+1; else ndir=1, row=row+1; botrow=botrow+1; end
elseif ndir=a(j+(i+k)) =1 v(j)
i = i+2*k
if row<toprow then row=row+1; else ndir=2, col=col-1; topcol=topcol-1; end
end
elseif ndir==2
a(cumsum(a)) = (1:n*n)'
if col>botcol then col=col-1; else ndir=3, row=row-1; toprow=toprow-1; end
a elseif= ndir==3matrix(a, n, n)'-1
endfunction
if row>botrow then row=row-1; else ndir=0, col=col+1; botcol=botcol+1; end
 
end
-->spiral(5)
end i
ans =
printf("n=%4d\n",n);
for i=1:n;
0. 1. 2. 3. 4.
for j=1:n; printf("%4d",mat(i,j)); end j; printf("\n");
15. 16. 17. 18. 5.
end i;</lang>
14. 23. 24. 19. 6.
{{out}}
13. 22. 21. 20. 7.
<pre style="height:20ex">n= 10
0 12. 1 11. 2 310. 4 9. 5 6 7 8 9.</syntaxhighlight>
35 36 37 38 39 40 41 42 43 10
34 63 64 65 66 67 68 69 44 11
33 62 83 84 85 86 87 70 45 12
32 61 82 95 96 97 88 71 46 13
31 60 81 94 99 98 89 72 47 14
30 59 80 93 92 91 90 73 48 15
29 58 79 78 77 76 75 74 49 16
28 57 56 55 54 53 52 51 50 17
27 26 25 24 23 22 21 20 19 18</pre>
 
=={{header|Seed7}}==
<langsyntaxhighlight lang="seed7">$ include "seed7_05.s7i";
 
const type: matrix is array array integer;
Line 3,389 ⟶ 5,151:
begin
writeMatrix(spiral(5));
end func;</langsyntaxhighlight>
{{out}}
<pre>
Line 3,401 ⟶ 5,163:
=={{header|Sidef}}==
{{trans|Perl}}
<langsyntaxhighlight lang="ruby">func spiral(n) {
var (x, y, dx, dy, a) = (0, 0, 1, 0, []);
{ |i|
a[y][x] = i;
var (nx, ny) = (x+dx, y+dy);
( if (dx == 1 && (nx == n || a[ny][nx]!=nil)) { [ 0, 1] }
elsif (dy == 1 && (ny == n || a[ny][nx]!=nil)) { [-1, 0] }
Line 3,411 ⟶ 5,173:
elsif (dy == -1 && (ny < 0 || a[ny][nx]!=nil)) { [ 1, 0] }
else { [dx, dy] }
)  » (\dx, \dy);
x = x+dx;
y = y+dy;
} *<< (1 .. n**2;)
return a;
}
 
 
spiral(5).each { |row|
row.map {"%3d" % _}.join(' ').say;
}</langsyntaxhighlight>
{{out}}
<pre>
Line 3,429 ⟶ 5,191:
13 12 11 10 9
</pre>
 
=={{header|Stata}}==
<syntaxhighlight lang="stata">function spiral_mat(n) {
a = J(n*n, 1, 1)
u = J(n, 1, -n)
v = J(n, 1, 1)
for (k=(i=n)-1; k>=1; i=i+2*k--) {
j = 1..k
a[j:+i] = u[j] = -u[j]
a[j:+(i+k)] = v[j] = -v[j]
}
return(rowshape(invorder(runningsum(a)),n):-1)
}
 
spiral_mat(5)
1 2 3 4 5
+--------------------------+
1 | 0 1 2 3 4 |
2 | 15 16 17 18 5 |
3 | 14 23 24 19 6 |
4 | 13 22 21 20 7 |
5 | 12 11 10 9 8 |
+--------------------------+</syntaxhighlight>
 
=={{header|Tcl}}==
Using <code>print_matrix</code> from [[Matrix Transpose#Tcl]]
<langsyntaxhighlight lang="tcl">package require Tcl 8.5
namespace path {::tcl::mathop}
proc spiral size {
Line 3,465 ⟶ 5,250:
}
 
print_matrix [spiral 5]</langsyntaxhighlight>
<pre> 0 1 2 3 4
15 16 17 18 5
Line 3,474 ⟶ 5,259:
=={{header|TI-83 BASIC}}==
{{trans|BBC Basic}}
<langsyntaxhighlight lang="ti83b">5->N
DelVar [F]
{N,N}→dim([F])
Line 3,513 ⟶ 5,298:
G→E
End
[F]</langsyntaxhighlight>
{{out}}
<pre>[[0 1 2 3 4]
Line 3,522 ⟶ 5,307:
 
=={{header|TSE SAL}}==
<syntaxhighlight lang="tse sal">
<lang TSE SAL>
 
// library: math: create: array: spiral: inwards <description></description> <version control></version control> <version>1.0.0.0.15</version> (filenamemacro=creamasi.s) [<Program>] [<Research>] [kn, ri, mo, 31-12-2012 01:15:43]
Line 3,651 ⟶ 5,436:
END
 
</syntaxhighlight>
</lang>
 
=={{header|uBasic/4tH}}==
{{trans|C}}
This recursive version is quite compact.
<syntaxhighlight lang="text">Input "Width: ";w
Input "Height: ";h
Print
 
For i = 0 To h-1
For j = 0 To w-1
Print Using "__#"; FUNC(_Spiral(w,h,j,i));
Next
Print
Next
End
 
 
_Spiral Param(4)
If d@ Then
Return (a@ + FUNC(_Spiral(b@-1, a@, d@ - 1, a@ - c@ - 1)))
Else
Return (c@)
EndIf</syntaxhighlight>
 
=={{header|Ursala}}==
Helpful hints from the [[#J|J]] example are gratefully acknowledged. The spiral function works for any n, and results are shown for n equal to 5, 6, and 7. The results are represented as lists of lists rather than arrays.
<langsyntaxhighlight Ursalalang="ursala">#import std
#import nat
#import int
Line 3,667 ⟶ 5,475:
#cast %nLLL
 
examples = spiral* <5,6,7></langsyntaxhighlight>
{{out}}
<pre>
Line 3,695 ⟶ 5,503:
=={{header|VBScript}}==
{{trans|BBC BASIC}}
<syntaxhighlight lang="vb">
<lang vb>
Function build_spiral(n)
botcol = 0 : topcol = n - 1
Line 3,743 ⟶ 5,551:
 
build_spiral(CInt(WScript.Arguments(0)))
</syntaxhighlight>
</lang>
 
{{Out}}
Line 3,768 ⟶ 5,576:
{{trans|Java}}
This requires VB6.
<langsyntaxhighlight lang="vb">Option Explicit
 
Sub Main()
Line 3,825 ⟶ 5,633:
Debug.Print arr(row, UBound(arr, 2))
Next
End Sub</langsyntaxhighlight>
 
==={{header|VBA}}===
Line 3,831 ⟶ 5,639:
{{trans|Java}}
{{works with|VBA/Excel}}
<langsyntaxhighlight lang="vb">Sub spiral()
Dim n As Integer, a As Integer, b As Integer
Dim numCsquares As Integer, sideLen As Integer, currNum As Integer
Line 3,881 ⟶ 5,689:
Next b
Next a
End Sub</langsyntaxhighlight>
 
====Solution 2====
<langsyntaxhighlight lang="vb">Sub spiral(n As Integer)
Const FREE = -9 'negative number indicates unoccupied cell
Dim A() As Integer
Line 3,951 ⟶ 5,759:
Next
End Sub</langsyntaxhighlight>
{{out}}
<pre>
Line 3,973 ⟶ 5,781:
'''Platform:''' [[.NET]]<br>
From VB6. This requires Visual Basic .Net.
<langsyntaxhighlight lang="vbnet">Module modSpiralArray
Sub Main()
print2dArray(getSpiralArray(5))
Line 4,028 ⟶ 5,836:
 
End Module
</syntaxhighlight>
</lang>
 
=={{header|Wren}}==
{{trans|Go}}
{{libheader|Wren-fmt}}
<syntaxhighlight lang="wren">import "./fmt" for Conv, Fmt
 
var n = 5
var top = 0
var left = 0
var bottom = n - 1
var right = n - 1
var sz = n * n
var a = List.filled(sz, 0)
var i = 0
while (left < right) {
// work right, along top
var c = left
while (c <= right) {
a[top*n+c] = i
i = i + 1
c = c + 1
}
top = top + 1
// work down right side
var r = top
while (r <= bottom) {
a[r*n+right] = i
i = i + 1
r = r + 1
}
right = right - 1
if (top == bottom) break
// work left, along bottom
c = right
while (c >= left) {
a[bottom*n+c] = i
i = i + 1
c = c - 1
}
bottom = bottom - 1
r = bottom
// work up left side
while (r >= top) {
a[r*n+left] = i
i = i + 1
r = r - 1
}
left = left + 1
}
// center (last) element
a[top*n+left] = i
 
// print
var w = Conv.itoa(n*n - 1).count
i = 0
for (e in a) {
Fmt.write("$*d ", w, e)
if (i%n == n - 1) System.print()
i = i + 1
}</syntaxhighlight>
 
{{out}}
<pre>
0 1 2 3 4
15 16 17 18 5
14 23 24 19 6
13 22 21 20 7
12 11 10 9 8
</pre>
 
=={{header|XPL0}}==
<langsyntaxhighlight XPL0lang="xpl0">def N=5;
int A(N,N);
int I, J, X, Y, Steps, Dir;
Line 4,052 ⟶ 5,929:
until Steps = 0;
Cursor(0,N);
]</langsyntaxhighlight>
 
{{out}}
Line 4,061 ⟶ 5,938:
13 22 21 20 7
12 11 10 9 8
</pre>
 
=={{header|Z80 Assembly}}==
N is set at beginning of code (valid range 1..150-ish, then you soon run out of memory), sjasmplus syntax, CP/M executable:
<syntaxhighlight lang="z80">; Spiral matrix in Z80 assembly (for CP/M OS - you can use `tnylpo` or `z88dk-ticks` on PC)
OPT --syntax=abf : OUTPUT "spiralmt.com" ; asm syntax for z00m's variant of sjasmplus
ORG $100
spiral_matrix:
ld a,5 ; N matrix size (argument for the code) (valid range: 1..150)
; setup phase
push af
ld l,a
ld h,0
add hl,hl
ld (delta_d),hl ; down-direction address delta = +N*2
neg
ld l,a
ld h,$FF
add hl,hl
ld (delta_u),hl ; up-direction address delta = -N*2
neg
ld hl,matrix
ld de,2 ; delta_r value to move right in matrix
ld bc,0 ; starting value
dec a ; first sequences will be N-1 long
jr z,.finish ; 1x1 doesn't need any sequence, just set last element
call set_sequence ; initial entry sequence has N-1 elements (same as two more)
; main loop - do twice same length sequence, then decrement length, until zero
.loop:
call set_sequence_twice
dec a
jr nz,.loop
.finish: ; whole spiral is set except last element, set it now
ld (hl),c
inc hl
ld (hl),b
; print matrix - reading it by POP HL (destructive, plus some memory ahead of matrix too)
pop de ; d = N
ld (.oldsp+1),sp
ld sp,matrix ; set stack to beginning of matrix (call/push does damage memory ahead)
ld c,d ; c = N (lines counter)
.print_rows:
ld b,d ; b = N (value per row counter)
.print_row:
pop hl
push de
push bc
call print_hl
pop bc
pop de
djnz .print_row
push de
call print_crlf
pop de
dec c
jr nz,.print_rows
.oldsp:
ld sp,0
rst 0 ; return to CP/M
 
print_crlf:
ld e,10
call print_char
ld e,13
jr print_char
print_hl:
ld b,' '
ld e,b
call print_char
ld de,-10000
call extract_digit
ld de,-1000
call extract_digit
ld de,-100
call extract_digit
ld de,-10
call extract_digit
ld a,l
print_digit:
ld b,'0'
add a,b
ld e,a
print_char:
push bc
push hl
ld c,2
call 5
pop hl
pop bc
ret
extract_digit:
ld a,-1
.digit_loop:
inc a
add hl,de
jr c,.digit_loop
sbc hl,de
or a
jr nz,print_digit
ld e,b
jr print_char
 
set_sequence_twice:
call set_sequence
set_sequence:
; A = length, HL = next_to_matrix, DE = delta to advance hl, BC = next_value
push af
.set_loop:
ld (hl),c
inc hl
ld (hl),b
dec hl ; [HL] = BC
add hl,de ; HL += DE
inc bc ; ++BC
dec a
jr nz,.set_loop
push hl ; change DE for next direction (right->down->left->up->right->...)
.d: ld hl,delta_d ; self-modify-code: pointer to next delta
ld e,(hl)
inc hl
ld d,(hl) ; de = address delta for next sequence
inc hl
ld a,low delta_u+2 ; if hl == delta_u+2 => reset it back to delta_r
cp l
jr nz,.next_delta
ld hl,delta_r
.next_delta:
ld (.d+1),hl ; self modify code pointer for next delta value
pop hl
pop af
ret
 
delta_r: dw +2 ; value to add to move right in matrix
delta_d: dw 0 ; value to add to move down in matrix (set to +N*2)
delta_l: dw -2 ; value to add to move left in matrix
delta_u: dw 0 ; value to add to move up in matrix (set to -N*2)
 
matrix:
; following memory is used for NxN matrix of uint16_t values (150x150 needs 45000 bytes)</syntaxhighlight>
 
{{out}}
<pre>
$ tnylpo spiralmt.com
0 1 2 3 4
15 16 17 18 5
14 23 24 19 6
13 22 21 20 7
12 11 10 9 8
</pre>
 
=={{header|zkl}}==
{{trans|C}} which turns out to be the same as Ruby
<langsyntaxhighlight lang="zkl">fcn spiralMatrix(n){
sm:=(0).pump(n,List,(0).pump(n,List,False).copy); //L(L(False,False..), L(F,F,..) ...)
drc:=Utils.HelpersWalker.cycle(T(0,1,0), T(1,0,1), T(0,-1,0), T(-1,0,1)); // deltas
len:=n; r:=0; c:=-1; z:=-1; while(len>0){ //or do(2*n-1){
dr,dc,dl:=drc.next();
Line 4,073 ⟶ 6,098:
}
sm
}</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">foreach n in (T(5,-1,0,1,2)){
spiralMatrix(n).pump(Console.println,fcn(r){ r.apply("%4d".fmt).concat() });
println("---");
}</langsyntaxhighlight>
{{out}}
<pre>
1,150

edits