Spiral matrix: Difference between revisions
m
→{{header|RPL}}: typo
ReeceGoding (talk | contribs) (→{{header|R}}: New iterative solution. Finished at 1am, so possibily in need of tidying.) |
m (→{{header|RPL}}: typo) |
||
(36 intermediate revisions by 18 users not shown) | |||
Line 24:
* [[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}}
<
USING SPIRALM,R13
SAVEAREA B STM-SAVEAREA(R15)
Line 147 ⟶ 179:
MATRIX DS H Matrix(n,n)
YREGS
END SPIRALM</
{{out}}
<pre> 0 1 2 3 4
Line 154 ⟶ 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}}==
<
with Ada.Text_Io; use Ada.Text_Io;
with Ada.Integer_Text_Io; use Ada.Integer_Text_Io;
Line 222 ⟶ 478:
begin
Print(Spiral(5));
end Spiral_Square;</
The following is a variant using a different algorithm (which can also be used recursively):
<
Result : Array_Type (1..N, 1..N);
Left : Positive := 1;
Line 256 ⟶ 512:
Result (Top, Left) := Index;
return Result;
end Spiral;</
=={{header|ALGOL 68}}==
Line 263 ⟶ 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]}}
<
PROC spiral = (INT n)[,]INT: (
Line 296 ⟶ 552:
);
print spiral(spiral(5))</
{{out}}
<pre>
Line 309 ⟶ 565:
{{Trans|JavaScript}} (ES6)
<syntaxhighlight lang="applescript">---------------------- SPIRAL MATRIX ---------------------
-- spiral :: Int -> [[Int]]
on spiral(n)
script go
Line 316 ⟶ 574:
{enumFromTo(start, start + pred(cols))} & ¬
map(my |reverse|, ¬
else
{{}}
Line 326 ⟶ 584:
end spiral
--------------------------- TEST -------------------------
on run
wikiTable(spiral(5), ¬
false, ¬
Line 334 ⟶ 592:
end run
-------------------- WIKI TABLE FORMAT -------------------
-- wikiTable :: [Text] -> Bool -> Text -> Text
Line 353 ⟶ 612:
end wikiTable
------------------------- GENERIC ------------------------
-- comparing :: (a -> b) -> (a -> a -> Ordering)
Line 373 ⟶ 633:
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]
Line 402 ⟶ 664:
end if
end enumFromTo
-- foldl :: (a -> b -> a) -> a -> [b] -> a
Line 414 ⟶ 677:
end tell
end foldl
-- if_ :: Bool -> a -> a -> a
Line 423 ⟶ 687:
end if
end if_
-- intercalateS :: String -> [String] -> String
Line 431 ⟶ 696:
return s
end intercalateS
-- length :: [a] -> Int
Line 436 ⟶ 702:
length of xs
end |length|
-- max :: Ord a => a -> a -> a
Line 445 ⟶ 712:
end if
end max
-- maximumBy :: (a -> a -> Ordering) -> [a] -> a
Line 461 ⟶ 729:
foldl(max, missing value, xs)
end maximumBy
-- Lift 2nd class handler function into 1st class script wrapper
Line 473 ⟶ 742:
end if
end mReturn
-- map :: (a -> b) -> [a] -> [b]
Line 485 ⟶ 755:
end tell
end map
-- pred :: Enum a => a -> a
on pred(x)
end pred
-- Egyptian multiplication - progressively doubling a list, appending
Line 518 ⟶ 790:
end |reverse|
-- Simplified version - assuming rows of unvarying length.
-- transpose :: [[a]] -> [[a]]
on transpose(
script cols
on |λ|(_, iCol)
Line 549 ⟶ 806:
map(cols, item 1 of rows)
end transpose
-- unlines :: [String] -> String
Line 558 ⟶ 816:
str
end unlines
-- unwords :: [String] -> String
on unwords(xs)
intercalateS(space, xs)
end unwords</
{{Out}}
{| class="wikitable" style="text-align:center;width:12em;height:12em;table-layout:fixed;"
Line 576 ⟶ 835:
| 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]
<
Loop % n*n {
Line 605 ⟶ 903:
13 12 11 10 9
---------------------------
*/</
=={{header|AWK}}==
<syntaxhighlight lang="awk">
# syntax: GAWK -f SPIRAL_MATRIX.AWK [-v offset={0|1}] [size]
# converted from BBC BASIC
Line 648 ⟶ 946:
exit(0)
}
</syntaxhighlight>
{{out}}
<pre>
Line 659 ⟶ 957:
=={{header|BBC BASIC}}==
<
@%=LENSTR$(N%*N%-1)+1
BotCol%=0 : TopCol%=N%-1
Line 676 ⟶ 974:
ENDCASE
NEXT
END</
=={{header|C}}==
Note: program produces a matrix starting from 1 instead of 0, because task says "natural numbers".
<
#include <stdlib.h>
Line 714 ⟶ 1,012:
return 0;
}</
Recursive method, width and height given on command line:
<
#include <stdlib.h>
Line 734 ⟶ 1,032:
}
return 0;
}</
=={{header|C sharp|C#}}==
Solution based on the [[#J|J]] hints:
<
int[,] result = new int[n, n];
Line 774 ⟶ 1,072:
Console.WriteLine();
}
}</
Translated proper C++ solution:
<
//generate spiral matrix for given N
Line 800 ⟶ 1,098:
}
}
</syntaxhighlight>
====Spiral Matrix without using an Array====
<
using System;
using System.Collections.Generic;
Line 876 ⟶ 1,174:
}
}
</syntaxhighlight>
{{Out}}
<
Enter order..
Line 908 ⟶ 1,206:
17 30 29 28 27 10
16 15 14 13 12 11
</syntaxhighlight>
=={{header|C++}}==
<
#include <memory> // for auto_ptr
#include <cmath> // for the ceil and log10 and floor functions
Line 977 ⟶ 1,275:
{
printSpiralArray( getSpiralArray( 5 ) );
}</
C++ solution done properly:
<
#include <iostream>
using namespace std;
Line 996 ⟶ 1,294:
cout << endl;
}
}</
=={{header|Clojure}}==
Based on the [[#J|J]] hints (almost as incomprehensible, maybe)
<
(let [cyc (cycle [1 n -1 (- n)])]
(->> (range (dec n) 0 -1)
Line 1,015 ⟶ 1,313:
true
(str " ~{~<~%~," (* n 3) ":;~2d ~>~}~%")
(spiral n)))</
Recursive generation:
{{trans|Common Lisp}}
<
(defn spiral-matrix [m n & [start]]
(let [row (list (map #(+ start %) (range m)))]
Line 1,027 ⟶ 1,325:
(defn spiral [n m] (spiral-matrix n m 1))
</syntaxhighlight>
=={{header|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 1,077 ⟶ 1,375:
console.log "\n----Spiral n=#{n}"
console.log spiral_matrix n
</syntaxhighlight>
{{out}}
<syntaxhighlight lang="text">
> coffee spiral.coffee
Line 1,098 ⟶ 1,396:
[ 19, 36, 35, 34, 33, 32, 11 ],
[ 18, 17, 16, 15, 14, 13, 12 ] ]
</syntaxhighlight>
=={{header|Common Lisp}}==
{{trans|Python}}
<
(do ((N (* rows columns))
(spiral (make-array (list rows columns) :initial-element nil))
Line 1,119 ⟶ 1,417:
dy dx)
(setf x (+ x dx)
y (+ y dy)))))))</
<pre>> (pprint (spiral 6 6))
Line 1,137 ⟶ 1,435:
(8 7 6))</pre>
Recursive generation:
<
(let ((row (list (loop for x from 0 to (1- m) collect (+ x start)))))
(if (= 1 n) row
Line 1,147 ⟶ 1,445:
;; test
(loop for row in (spiral 4 3) do
(format t "~{~4d~^~}~%" row))</
=={{header|D}}==
<
import std.stdio;
enum n = 5;
Line 1,169 ⟶ 1,467:
writefln("%(%(%2d %)\n%)", M);
}</
{{out}}
<pre> 0 1 2 3 4
Line 1,177 ⟶ 1,475:
12 11 10 9 8</pre>
Using a generator for any rectangular array:
<
/// 2D spiral generator
Line 1,228 ⟶ 1,526:
foreach (r; spiralMatrix(9, 4))
writefln("%(%2d %)", r);
}</
{{out}}
<pre> 0 1 2 3 4 5 6 7 8
Line 1,236 ⟶ 1,534:
=={{header|DCL}}==
<
$ max = p1 * p1
$
Line 1,291 ⟶ 1,589:
$ endif
$ endif
$ return</
{{out}}
<pre>$ @spiral_matrix 3
Line 1,305 ⟶ 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 1,310 ⟶ 1,737:
{{E 2D utilities}}
<
def array := makeFlex2DArray(size, size)
var i := -1 # Counter of numbers to fill
Line 1,334 ⟶ 1,761:
return array
}</
Example:
<
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|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}}
<
def spiral_matrix(n) do
wide = length(to_char_list(n*n-1))
Line 1,363 ⟶ 1,834:
end
RC.spiral_matrix(5)</
'''The other way'''
<
def spiral_matrix(n) do
wide = String.length(to_string(n*n-1))
Line 1,395 ⟶ 1,866:
end
RC.spiral_matrix(5)</
'''Another way'''
<
def spiral_matrix(n) do
fmt = String.duplicate("~#{length(to_char_list(n*n-1))}w ", n) <> "~n"
Line 1,416 ⟶ 1,887:
end
RC.spiral_matrix(5)</
{{out}}
Line 1,428 ⟶ 1,899:
=={{header|Euphoria}}==
<
integer side, curr, curr2
sequence s
Line 1,456 ⟶ 1,927:
end function
? spiral(5)</
{{out}}
Line 1,469 ⟶ 1,940:
=={{header|F_Sharp|F#}}==
No fancy schmancy elegance here, just putting the numbers in the right place (though I commend the elegance)...
<
let sq = Array2D.create n n 0 // Set up an output array
let nCur = ref -1 // Current value being inserted
Line 1,482 ⟶ 1,953:
[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</
=={{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.
<
math.ranges math.statistics prettyprint sequences
sequences.repeating ;
Line 1,504 ⟶ 1,975:
: spiral-demo ( -- ) 5 9 [ spiral simple-table. nl ] bi@ ;
MAIN: spiral-demo</
{{out}}
<pre>
Line 1,526 ⟶ 1,997:
=={{header|Fortran}}==
{{works with|Fortran|90 and later}}
<
IMPLICIT NONE
Line 1,574 ⟶ 2,045:
END DO
END PROGRAM SPIRAL</
=={{header|FreeBASIC}}==
<
Enum Direction
Line 1,652 ⟶ 2,123:
Print
Print "Press any key to quit"
Sleep</
{{out}}
Line 1,666 ⟶ 2,137:
=={{header|GAP}}==
<
SpiralMatrix := function(n)
local i, j, k, di, dj, p, vi, vj, imin, imax, jmin, jmax;
Line 1,712 ⟶ 2,183:
# [ 15, 24, 25, 20, 7 ],
# [ 14, 23, 22, 21, 8 ],
# [ 13, 12, 11, 10, 9 ] ]</
=={{header|Go}}==
<
import (
Line 1,772 ⟶ 2,243:
}
}
}</
=={{header|Groovy}}==
Naive "path-walking" solution:
<
East([0,1]), South([1,0]), West([0,-1]), North([-1,0]);
private static _n
Line 1,829 ⟶ 2,300:
}
M
}</
Test:
<
spiralMatrix(n).each { row ->
row.each { printf "%5d", it }
Line 1,837 ⟶ 2,308:
}
println ()
}</
{{out}}
<pre style="height:30ex;overflow:scroll;"> 0
Line 1,906 ⟶ 2,377:
=={{header|Haskell}}==
Solution based on the [[#J|J]] hints:
<
import Control.Monad
grade xs = map snd. sort $ zip xs [0..]
Line 1,914 ⟶ 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</
An alternative, point-free solution based on the same J source.
<
import Control.Applicative
counts = tail . reverse . concat . map (replicate 2) . enumFromTo 1
Line 1,926 ⟶ 2,397:
parts = (<*>) take $ (.) <$> (map . take) <*> (iterate . drop) <*> copies
disp = (>> return ()) . mapM (putStrLn . intercalate " " . map show) . parts
main = disp 5</
Another alternative:
<
import Text.Printf (printf)
Line 1,938 ⟶ 2,409:
-- this is sort of hideous, someone may want to fix it
main = mapM_ (\row->mapM_ ((printf "%4d").toInteger) row >> putStrLn "") (spiral 10 9 1)</
Or less ambitiously,
{{Trans|AppleScript}}
<
---------------------- SPIRAL MATRIX ---------------------
spiral :: Int -> [[Int]]
spiral n = go n n 0
Line 1,951 ⟶ 2,422:
go rows cols x
| 0 < rows =
[x .. pred cols + x] :
fmap
reverse
(transpose $ go cols (pred rows) (x + cols))
| otherwise = [[]]
--
main :: IO ()
main = putStrLn $ wikiTable $ spiral 5
--------------------- TABLE FORMATTING -------------------
wikiTable :: Show a => [[a]] -> String
wikiTable =
. ("{| class=\"wikitable\" style=\"text-align: right;" :)
. ("width:12em;height:12em;table-layout:fixed;\"\n|-\n" :)
. (
. intercalate "\n|-\n"
. fmap (('|' :) . (' ' :) . intercalate " || " . fmap show)</
{{Out}}
{| class="wikitable" style="text-align: right;width:12em;height:12em;table-layout:fixed;"|-
Line 1,982 ⟶ 2,459:
=={{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.
<
N := 0 < integer(\A[1]|5) # N=1... (dfeault 5)
WriteMatrix(SpiralMatrix(N))
Line 2,009 ⟶ 2,486:
}
return M
end</
{{out}}
Line 2,019 ⟶ 2,496:
=={{header|IS-BASIC}}==
<
110 TEXT 80
120 INPUT PROMPT "Enter size of matrix (max. 10): ":N
Line 2,064 ⟶ 2,541:
530 PRINT
540 NEXT
550 END DEF</
=={{header|J}}==
This function is the result of
some [http://www.jsoftware.com/papers/play132.htm beautiful insights]:
<
spiral 5
Line 2,076 ⟶ 2,553:
14 23 24 19 6
13 22 21 20 7
12 11 10 9 8</
Would you like [[Talk:Spiral#J|some hints]] that will allow you to reimplement it in another language?
Line 2,084 ⟶ 2,561:
{{trans|C++}}
{{works with|Java|1.5+}}
<
public static void main(String[] args) {
Line 2,134 ⟶ 2,611:
}
}
}</
{{out}}
<pre> 0 1 2 3 4
Line 2,146 ⟶ 2,623:
===Imperative===
<
var arr = Array(edge),
x = 0, y = edge,
Line 2,167 ⟶ 2,644:
arr = spiralArray(edge = 5);
for (y= 0; y < edge; y++) console.log(arr[y].join(" "));
</syntaxhighlight>
{{out}}
<pre>
Line 2,182 ⟶ 2,659:
Translating one of the Haskell versions:
<
// Spiral: the first row plus a smaller spiral rotated 90 degrees clockwise
Line 2,248 ⟶ 2,725:
].join('\n\n');
})(5);</
Output:
Line 2,265 ⟶ 2,742:
|}
<
====ES6====
{{Trans|Haskell}}
<
// ------------------ SPIRAL MATRIX ------------------
// spiral :: Int -> [[Int]]
const spiral = n => {
const go = (rows, cols, start) =>
enumFromTo(start
...
start
)
).map(reverse)
] : [
[]
];
return go(n, n, 0);
};
// ---------------------- TEST -----------------------
const main
cellWidth = 1 +
return unlines(
spiral(n).map(
);
};
// --------------------- GENERIC ---------------------
// enumFromTo :: Int -> Int -> [Int]
const enumFromTo = m =>
}, (_, i) => m + i);
// pred :: Enum a => a -> a
const pred = x => x - 1;
// reverse :: [a] -> [a]
const reverse = xs =>
xs.
) : xs.slice(0).reverse();
// transpose :: [[a]] -> [[a]]
const transpose =
// The columns of the input transposed
// into new
// Simpler version of transpose, assuming input
// rows of even
Boolean(rows.length)
) : [];
// 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();
})();</
{{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 2,406 ⟶ 2,849:
'''Infrastructure''':
<
def matrix(m; n; init):
if m == 0 then []
Line 2,431 ⟶ 2,874:
elif . == [0, 1] then [ 1, 0]
else error("invalid direction: \(.)")
end;</
'''Create a spiral n by n matrix'''
<
# we just placed m at i,j, and we are moving in the direction d
def _next(i; j; m; d):
Line 2,446 ⟶ 2,889:
# Example
spiral(5) | neatly(3)</
{{Out}}
$ jq -n -r -f spiral.jq
Line 2,459 ⟶ 2,902:
'''Spiral Matrix Iterator'''
<syntaxhighlight lang="julia">
immutable Spiral
m::Int
Line 2,503 ⟶ 2,946:
return (s, sps)
end
</syntaxhighlight>
'''Helper Functions'''
<syntaxhighlight lang="julia">
using Formatting
Line 2,531 ⟶ 2,974:
return s
end
</syntaxhighlight>
'''Main'''
<syntaxhighlight lang="julia">
n = 5
println("The n = ", n, " spiral matrix:")
Line 2,561 ⟶ 3,004:
end
println(pretty(a))
</syntaxhighlight>
{{out}}
Line 2,589 ⟶ 3,032:
=={{header|Kotlin}}==
{{trans|C#}}
<
typealias Vector = IntArray
Line 2,628 ⟶ 3,071:
printMatrix(spiralMatrix(5))
printMatrix(spiralMatrix(10))
}</
{{out}}
Line 2,652 ⟶ 3,095:
=={{header|Liberty BASIC}}==
Extended to include automatic scaling of the display scale and font. See [http://www.diga.me.uk/spiralM5.gif spiralM5]
<
UpperLeftX = 50
Line 2,727 ⟶ 3,170:
[quit]
close #w
end</
=={{header|Lua}}==
===Original===
<
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 2,749 ⟶ 3,192:
end
for i,v in ipairs(spiralt(8)) do for j, u in ipairs(v) do io.write(u .. " ") end print() end</
===Alternate===
If only the printed output is required, without intermediate array storage, then:
<
local function z(x,y)
local m = math.min(x, y, n-1-x, n-1-y)
Line 2,765 ⟶ 3,208:
end
end
printspiral(9)</
If the intermediate array storage ''is'' required, then:
<
local t, z = {}, function(x,y)
local m = math.min(x, y, n-1-x, n-1-y)
Line 2,785 ⟶ 3,228:
end
end
printspiral(makespiral(9))</
{{out}}
(same for both)
Line 2,800 ⟶ 3,243:
=={{header|Maple}}==
<syntaxhighlight lang="maple">
with(ArrayTools):
Line 2,828 ⟶ 3,271:
spiralArray(5);
</syntaxhighlight>
{{out}}<pre>
[ 0 1 2 3 4]
Line 2,844 ⟶ 3,287:
=={{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':
<
size=Length[x];
smallest=x[[1,1]];
Line 2,859 ⟶ 3,302:
times=If[Mod[size,2]==0,size/2-1,(size-1)/2];
Nest[AddSquareRing,start,times]
]</
Examples:
<
MakeSquareSpiral[7] // MatrixForm</
gives back:
<math>
Line 2,893 ⟶ 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.
<
matrix = (-spiral(n))+n^2;
Line 2,903 ⟶ 3,346:
end
end %reverseSpiral</
Sample Usage:
<
ans =
Line 2,913 ⟶ 3,356:
14 23 24 19 6
13 22 21 20 7
12 11 10 9 8</
=={{header|Maxima}}==
<
a: zeromatrix(n, n),
vi: [1, 0, -1, 0],
Line 2,955 ⟶ 3,398:
[15, 24, 25, 20, 7],
[14, 23, 22, 21, 8],
[13, 12, 11, 10, 9]) */</
=={{header|MiniZinc}}==
<syntaxhighlight lang="minizinc">
%Spiral Matrix. Nigel Galloway, February 3rd., 2020
int: Size;
Line 2,967 ⟶ 3,410:
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>
Line 3,000 ⟶ 3,443:
=={{header|NetRexx}}==
{{Trans|ooRexx}}
<
options replace format comments java crossref symbols binary
Line 3,092 ⟶ 3,535:
return maxNum
</syntaxhighlight>
{{out}}
Line 3,113 ⟶ 3,556:
=={{header|Nim}}==
<
proc `$`(m: seq[seq[int]]): string =
for r in m:
let lg = result.len
for c in r:
result.
result.add
result.add '\n'
proc spiral(n: Positive):
result = newSeqWith(n,
var dx = 1
var dy, x, y = 0
for i in 0 ..
result[y][x] = i
let (nx, ny) = (x+dx, y+dy)
if nx in 0 ..
x = nx
y = ny
Line 3,152 ⟶ 3,579:
swap dx, dy
dx = -dx
echo spiral(5)</
{{out}}
<pre> 0 1 2 3 4
Line 3,164 ⟶ 3,591:
=={{header|OCaml}}==
<
| 1, 0 -> 0, -1
| 0, 1 -> 1, 0
Line 3,202 ⟶ 3,629:
print_newline())
let () = print(spiral 5)</
Another implementation:
<
let ar = Array.make_matrix n n (-1) in
let out i = i < 0 || i >= n in
Line 3,221 ⟶ 3,648:
Array.iter (fun v -> Array.iter (Printf.printf " %2d") v; print_newline())
let _ = show (spiral 5)</
=={{header|Octave}}==
{{trans|Stata}}
<
a = ones(n*n, 1);
u = -(i = n) * (v = ones(n, 1));
Line 3,245 ⟶ 3,672:
14 23 24 19 6
13 22 21 20 7
12 11 10 9 8</
=={{header|ooRexx}}==
<syntaxhighlight lang="oorexx">
call printArray generateArray(3)
say
Line 3,304 ⟶ 3,731:
say line
end
</syntaxhighlight>
{{out}}
<pre>
Line 3,325 ⟶ 3,752:
=={{header|Oz}}==
Simple, recursive solution:
<
fun {Spiral N}
%% create nested array
Line 3,366 ⟶ 3,793:
end
in
{Inspect {Spiral 5}}</
=={{header|PARI/GP}}==
<
my (M = matrix(dim, dim), p = s = 1, q = i = 0);
for (n=1, dim,
Line 3,378 ⟶ 3,805:
);
M
}</
Output:<pre>spiral(7)
Line 3,397 ⟶ 3,824:
=={{header|Pascal}}==
<
type
tDir = (left,down,right,up);
Line 3,467 ⟶ 3,894:
end;
END.
</syntaxhighlight>
{{out}}
<pre> 1
Line 3,482 ⟶ 3,909:
=={{header|Perl}}==
<
{my ($n, $x, $y, $dx, $dy, @a) = (shift, 0, 0, 1, 0);
foreach (0 .. $n**2 - 1)
Line 3,502 ⟶ 3,929:
foreach (spiral 5)
{printf "%3d", $_ foreach @$_;
print "\n";}</
=={{header|Phix}}==
{{
Simple is better.
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<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>
Line 3,538 ⟶ 3,965:
=={{header|PicoLisp}}==
This example uses 'grid' from "lib/simul.l", which maintains a two-dimensional structure and is normally used for simulations and board games.
<
(de spiral (N)
Line 3,556 ⟶ 3,983:
(for This L (prin (align 3 (: val))))
(prinl) )
(spiral 5) )</
{{out}}
<pre> 1 2 3 4 5
Line 3,565 ⟶ 3,992:
=={{header|PL/I}}==
<
/* where N is the length of one side of the square. */
/* Written 22 February 2010. */
Line 3,619 ⟶ 4,046:
end;
end;</
=={{header|PowerShell}}==
<
{
# Initialize variables
Line 3,657 ⟶ 4,084:
Spiral-Matrix 5
""
Spiral-Matrix 7</
{{out}}
<pre>1 2 3 4 5
Line 3,674 ⟶ 4,101:
=={{header|Prolog}}==
<syntaxhighlight lang="prolog">
% Prolog implementation: SWI-Prolog 7.2.3
Line 3,726 ⟶ 4,153:
Sq is N*N-1, numlist(0, Sq, Ns),
create(N, EMx), spiralH(right, EMx, (0,0), Ns, Mx).
</syntaxhighlight>
{{out}}
<pre>
Line 3,740 ⟶ 4,167:
=={{header|PureBasic}}==
{{trans|Fortran}}
<
Protected i, x = -1, y, count = size, n
Dim a(size - 1,size - 1)
Line 3,796 ⟶ 4,223:
Input()
CloseConsole()
EndIf</
{{out}}
<pre>Spiral: 2
Line 3,813 ⟶ 4,240:
=={{header|Python}}==
<
dx,dy = 1,0 # Starting increments
x,y = 0,0 # Starting location
Line 3,834 ⟶ 4,261:
print
printspiral(spiral(5))</
{{out}}
<pre>
Line 3,845 ⟶ 4,272:
===Recursive Solution===
<
def spiral_part(x, y, n):
if x == -1 and y == 0:
Line 3,867 ⟶ 4,294:
for row in spiral(5):
print " ".join("%2s" % x for x in row)</
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,
<
return zip(*a[::-1])
Line 3,889 ⟶ 4,316:
for row in spiral(5):
print(''.join('%3i' % i for i in row))</
Another way, based on preparing lists ahead
<
dat = [[None] * n for i in range(n)]
le = [[i + 1, i + 1] for i in reversed(range(n))]
Line 3,908 ⟶ 4,335:
for row in spiral(5): # calc spiral and print it
print ' '.join('%3s' % x for x in row)</
===Functional Solutions===
{{works with|Python|2.6, 3.0}}
<
concat = itertools.chain.from_iterable
Line 3,930 ⟶ 4,357:
for row in spiral(5):
print(' '.join('%3s' % x for x in row))</
Line 3,936 ⟶ 4,363:
{{Works with|Python|3.7}}
{{Trans|Haskell}}
<
Line 3,944 ⟶ 4,371:
'''
def go(rows, cols, x):
return [
in zip(*go(cols, rows - 1, x + cols))
] if 0 < rows else [[]]
Line 3,951 ⟶ 4,378:
#
# main :: IO ()
def main():
'''Spiral matrix of order 5, in wiki table markup
'''
print
wikiTable(spiral(5))
#
# wikiTable :: [[a]] -> String
Line 3,968 ⟶ 4,395:
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
# MAIN ---
if __name__ == '__main__':
main()
</syntaxhighlight>
{| class="wikitable" style="width:12em;height:12em;table-layout:fixed;"|-
| 0 || 1 || 2 || 3 || 4
Line 3,990 ⟶ 4,420:
=== Simple solution ===
<
m = [[0] * n for i in range(n)]
dx, dy = [0, 1, 0, -1], [1, 0, -1, 0]
Line 4,001 ⟶ 4,431:
c += 1
return m
for i in spiral_matrix(5): print(*i)</
{{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</
=={{header|Quackery}}==
This task really lends itself to a turtle graphics metaphor.
<syntaxhighlight lang="quackery"> [ stack ] is stepcount ( --> s )
[ stack ] is position ( --> s )
[ stack ] is heading ( --> s )
[ 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}}
[
[
[
[
[5,] 12 11 10 9 8</pre>
===Recursive Solution===
<
spiralv <- function(v) {
n <- sqrt(length(v))
Line 4,054 ⟶ 4,531:
}
spiralv(1:(n^2))
}</
===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.
<
{
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)
writeRight <- function(seq)
while(firstNumToWrite != n^2)
{
writingDirectionIndex <- writingDirectionIndex %% 4 + 1
seq <-
switch(writingDirectionIndex,
writeRight(seq),
Line 4,078 ⟶ 4,555:
writeRight(-seq),
writeDown(-seq))
if(writingDirectionIndex %% 2
max <- max(spiral)
firstNumToWrite <- max + 1
startPt <- which(max == spiral, arr.ind = TRUE)
}
spiral
}</
=={{header|Racket}}==
<
#lang racket
(require math)
Line 4,112 ⟶ 4,589:
(vector->matrix 4 4 (spiral 4 4))
</syntaxhighlight>
{{out}}
<
(mutable-array #[#[0 1 2 3] #[11 12 13 4] #[10 15 14 5] #[9 8 7 6]])
</syntaxhighlight>
=={{header|Raku}}==
Line 4,122 ⟶ 4,599:
===Object-oriented Solution===
Suppose we set up a Turtle class like this:
<syntaxhighlight lang="raku"
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.
Line 4,180 ⟶ 4,657:
}
$t.showmap;
}</
Or we can build the spiral from inside-out like this:
<syntaxhighlight lang="raku"
my $t = Turtle.new(dir => ($size %% 2 ?? 4 !! 0));
my $counter = $size * $size;
Line 4,194 ⟶ 4,671:
}
$t.showmap;
}</
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"
my @sm;
my $len = $n;
Line 4,216 ⟶ 4,693:
}
say .fmt('%3d') for spiral_matrix(5);</
{{out}}
<pre> 0 1 2 3 4
Line 4,227 ⟶ 4,704:
Original logic borrowed (mostly) from the [[#Fortran|Fortran]] example.
===static column width===
<
parse arg size start . /*obtain optional arguments from the CL*/
if size =='' | size =="," then size =5 /*Not specified? Then use the default.*/
Line 4,248 ⟶ 4,725:
end /*col*/ /* [↑] line has an extra leading blank*/
say _ /*display a line (row) of the spiral. */
end /*row*/ /*stick a fork in it, we're all done. */</
{{out|output|text= using the default array size of: '''5'''}}
<pre>
Line 4,314 ⟶ 4,791:
===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).
<
parse arg size start . /*obtain optional arguments from the CL*/
if size =='' | size =="," then size =5 /*Not specified? Then use the default.*/
Line 4,339 ⟶ 4,816:
if two then say substr(_, 2) /*this SUBSTR ignores the first blank. */
end /*r*/
end /*two*/ /*stick a fork in it, we're all done. */</
{{out|output|text= (shown at <sup>3</sup>/<sub>4</sub> size) using an array size of: '''36'''
<b>
Line 4,383 ⟶ 4,860:
=={{header|Ring}}==
<
# Project : Spiral matrix
Line 4,437 ⟶ 4,914:
exec()
}
</syntaxhighlight>
Output:
[http://
=={{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}}
<
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 4,461 ⟶ 4,961:
end
print_matrix spiral(5)</
{{out}}
<pre>
Line 4,473 ⟶ 4,973:
The other way
{{trans|D}}
<
m = Array.new(n){Array.new(n)}
pos, side = -1, n
Line 4,485 ⟶ 4,985:
fmt = "%#{(n*n-1).to_s.size}d " * n
puts m.map{|row| fmt % row}</
Output as above.
Line 4,491 ⟶ 4,991:
It processes the Array which is for work without creating it.
<
x, y, dx, dy = -1, 0, 0, -1
fmt = "%#{(n*n-1).to_s.size}d " * n
Line 4,500 ⟶ 5,000:
end
spiral_matrix(5)</
=={{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}}==
<
var dir = (1,0)
var pos = (-1,0)
Line 4,524 ⟶ 5,061:
folds.foreach {len => fold(seq.take(len),array); seq = seq.drop(len)}
array
}</
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 4,536 ⟶ 5,073:
=={{header|Scilab}}==
{{trans|Octave}}
<syntaxhighlight lang="text">function a = spiral(n)
a = ones(n*n, 1)
v = ones(n, 1)
Line 4,560 ⟶ 5,097:
14. 23. 24. 19. 6.
13. 22. 21. 20. 7.
12. 11. 10. 9. 8.</
=={{header|Seed7}}==
<
const type: matrix is array array integer;
Line 4,614 ⟶ 5,151:
begin
writeMatrix(spiral(5));
end func;</
{{out}}
<pre>
Line 4,626 ⟶ 5,163:
=={{header|Sidef}}==
{{trans|Perl}}
<
var (x, y, dx, dy, a) = (0, 0, 1, 0, [])
{ |i|
Line 4,645 ⟶ 5,182:
spiral(5).each { |row|
row.map {"%3d" % _}.join(' ').say
}</
{{out}}
<pre>
Line 4,656 ⟶ 5,193:
=={{header|Stata}}==
<
a = J(n*n, 1, 1)
u = J(n, 1, -n)
Line 4,676 ⟶ 5,213:
4 | 13 22 21 20 7 |
5 | 12 11 10 9 8 |
+--------------------------+</
=={{header|Tcl}}==
Using <code>print_matrix</code> from [[Matrix Transpose#Tcl]]
<
namespace path {::tcl::mathop}
proc spiral size {
Line 4,713 ⟶ 5,250:
}
print_matrix [spiral 5]</
<pre> 0 1 2 3 4
15 16 17 18 5
Line 4,722 ⟶ 5,259:
=={{header|TI-83 BASIC}}==
{{trans|BBC Basic}}
<
DelVar [F]
{N,N}→dim([F])
Line 4,761 ⟶ 5,298:
G→E
End
[F]</
{{out}}
<pre>[[0 1 2 3 4]
Line 4,770 ⟶ 5,307:
=={{header|TSE SAL}}==
<syntaxhighlight 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 4,899 ⟶ 5,436:
END
</syntaxhighlight>
=={{header|uBasic/4tH}}==
{{trans|C}}
This recursive version is quite compact.
<syntaxhighlight lang="text">Input "Width: ";w
Input "Height: ";h
Print
Line 4,922 ⟶ 5,459:
Else
Return (c@)
EndIf</
=={{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.
<
#import nat
#import int
Line 4,938 ⟶ 5,475:
#cast %nLLL
examples = spiral* <5,6,7></
{{out}}
<pre>
Line 4,966 ⟶ 5,503:
=={{header|VBScript}}==
{{trans|BBC BASIC}}
<syntaxhighlight lang="vb">
Function build_spiral(n)
botcol = 0 : topcol = n - 1
Line 5,014 ⟶ 5,551:
build_spiral(CInt(WScript.Arguments(0)))
</syntaxhighlight>
{{Out}}
Line 5,039 ⟶ 5,576:
{{trans|Java}}
This requires VB6.
<
Sub Main()
Line 5,096 ⟶ 5,633:
Debug.Print arr(row, UBound(arr, 2))
Next
End Sub</
==={{header|VBA}}===
Line 5,102 ⟶ 5,639:
{{trans|Java}}
{{works with|VBA/Excel}}
<
Dim n As Integer, a As Integer, b As Integer
Dim numCsquares As Integer, sideLen As Integer, currNum As Integer
Line 5,152 ⟶ 5,689:
Next b
Next a
End Sub</
====Solution 2====
<
Const FREE = -9 'negative number indicates unoccupied cell
Dim A() As Integer
Line 5,222 ⟶ 5,759:
Next
End Sub</
{{out}}
<pre>
Line 5,244 ⟶ 5,781:
'''Platform:''' [[.NET]]<br>
From VB6. This requires Visual Basic .Net.
<
Sub Main()
print2dArray(getSpiralArray(5))
Line 5,299 ⟶ 5,836:
End Module
</syntaxhighlight>
=={{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}}==
<
int A(N,N);
int I, J, X, Y, Steps, Dir;
Line 5,323 ⟶ 5,929:
until Steps = 0;
Cursor(0,N);
]</
{{out}}
Line 5,332 ⟶ 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
<
sm:=(0).pump(n,List,(0).pump(n,List,False).copy); //L(L(False,False..), L(F,F,..) ...)
drc:=Walker.cycle(T(0,1,0), T(1,0,1), T(0,-1,0), T(-1,0,1)); // deltas
Line 5,344 ⟶ 6,098:
}
sm
}</
<
spiralMatrix(n).pump(Console.println,fcn(r){ r.apply("%4d".fmt).concat() });
println("---");
}</
{{out}}
<pre>
|