Zig-zag matrix: Difference between revisions

m
 
(227 intermediate revisions by 77 users not shown)
Line 1:
{{task|Matrices}}
Produce a zig-zag array. A zig-zag array is a square arrangement of the first <tt>N<sup>2</sup></tt> integers, where the numbers increase sequentially as you zig-zag along the anti-diagonals of the array. For a graphical representation, see [[wp:Image:JPEG_ZigZag.svg|JPG zigzag]] (JPG uses such arrays to encode images).
 
;Task:
For example, given <tt>5</tt>, produce this array:
Produce a zig-zag array.
 
 
A &nbsp; ''zig-zag'' &nbsp; array 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 zig-zag along the array's &nbsp; [https://en.wiktionary.org/wiki/antidiagonal anti-diagonals].
 
For a graphical representation, see &nbsp; [[wp:Image:JPEG_ZigZag.svg|JPG zigzag]] &nbsp; (JPG uses such arrays to encode images).
 
 
For example, given &nbsp; '''5''', &nbsp; produce this array:
<pre>
0 1 5 6 14
Line 9 ⟶ 18:
9 11 17 20 22
10 18 19 23 24
</pre>
 
 
;Related tasks:
* &nbsp; [[Spiral matrix]]
* &nbsp; [[Identity matrix]]
* &nbsp; [[Ulam spiral (for primes)]]
 
 
;See also:
* &nbsp; Wiktionary entry: &nbsp; [https://en.wiktionary.org/wiki/antidiagonal anti-diagonals]
<br><br>
 
=={{header|11l}}==
{{trans|Python}}
 
<syntaxhighlight lang="11l">F zigzag(n)
F compare(xy)
V (x, y) = xy
R (x + y, I (x + y) % 2 {-y} E y)
V xs = 0 .< n
R Dict(enumerate(sorted((multiloop(xs, xs, (x, y) -> (x, y))), key' compare)), (n, index) -> (index, n))
 
F printzz(myarray)
V n = Int(myarray.len ^ 0.5 + 0.5)
V xs = 0 .< n
print((xs.map(y -> @xs.map(x -> ‘#3’.format(@@myarray[(x, @y)])).join(‘’))).join("\n"))
 
printzz(zigzag(6))</syntaxhighlight>
 
{{out}}
<pre>
0 2 3 9 10 20
1 4 8 11 19 21
5 7 12 18 22 29
6 13 17 23 28 30
14 16 24 27 31 34
15 25 26 32 33 35
</pre>
 
=={{header|360 Assembly}}==
<syntaxhighlight lang="360asm">* Zig-zag matrix 15/08/2015
ZIGZAGMA CSECT
USING ZIGZAGMA,R12 set base register
LR R12,R15 establish addressability
LA R9,N n : matrix size
LA R6,1 i=1
LA R7,1 j=1
LR R11,R9 n
MR R10,R9 *n
BCTR R11,0 R11=n**2-1
SR R8,R8 k=0
LOOPK CR R8,R11 do k=0 to n**2-1
BH ELOOPK k>limit
LR R1,R6 i
BCTR R1,0 -1
MR R0,R9 *n
LR R2,R7 j
BCTR R2,0 -1
AR R1,R2 (i-1)*n+(j-1)
SLA R1,1 index=((i-1)*n+j-1)*2
STH R8,T(R1) t(i,j)=k
LR R2,R6 i
AR R2,R7 i+j
LA R1,2 2
SRDA R2,32 shift right r1 to r2
DR R2,R1 (i+j)/2
LTR R2,R2 if mod(i+j,2)=0
BNZ ELSEMOD
CR R7,R9 if j<n
BNL ELSE1
LA R7,1(R7) j=j+1
B EIF1
ELSE1 LA R6,2(R6) i=i+2
EIF1 CH R6,=H'1' if i>1
BNH NOT1
BCTR R6,0 i=i-1
NOT1 B NOT2
ELSEMOD CR R6,R9 if i<n
BNL ELSE2
LA R6,1(R6) i=i+1
B EIF2
ELSE2 LA R7,2(R7) j=j+2
EIF2 CH R7,=H'1' if j>1
BNH NOT2
BCTR R7,0 j=j-1
NOT2 LA R8,1(R8) k=k+1
B LOOPK
ELOOPK LA R6,1 end k; i=1
LOOPI CR R6,R9 do i=1 to n
BH ELOOPI i>n
LA R10,0 ibuf=0 buffer index
MVC BUFFER,=CL80' '
LA R7,1 j=1
LOOPJ CR R7,R9 do j=1 to n
BH ELOOPJ j>n
LR R1,R6 i
BCTR R1,0 -1
MR R0,R9 *n
LR R2,R7 j
BCTR R2,0 -1
AR R1,R2 (i-1)*n+(j-1)
SLA R1,1 index=((i-1)*n+j-1)*2
LH R2,T(R1) t(i,j)
LA R3,BUFFER
AR R3,R10
XDECO R2,XDEC edit t(i,j) length=12
MVC 0(4,R3),XDEC+8 move in buffer length=4
LA R10,4(R10) ibuf=ibuf+1
LA R7,1(R7) j=j+1
B LOOPJ
ELOOPJ XPRNT BUFFER,80 end j
LA R6,1(R6) i=i+1
B LOOPI
ELOOPI XR R15,R15 end i; return_code=0
BR R14 return to caller
N EQU 5 matrix size
BUFFER DS CL80
XDEC DS CL12
T DS (N*N)H t(n,n) matrix
YREGS
END ZIGZAGMA</syntaxhighlight>
{{out}}
<pre>
0 1 5 6 14
2 4 7 13 15
3 8 12 16 21
9 11 17 20 22
10 18 19 23 24
</pre>
 
=={{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)
BYTE start,end
INT dir,i,j
 
start=0 end=size*size-1
i=0 j=0 dir=1
 
DO
a(Index(size,i,j))=start
a(Index(size,size-1-i,size-1-j))=end
start==+1 end==-1
i==+dir j==-dir
IF i<0 THEN
i==+1 dir=-dir
ELSEIF j<0 THEN
j==+1 dir=-dir
FI
UNTIL start>=end
OD
 
IF start=end THEN
a(Index(size,i,j))=start
FI
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/Zig-zag_matrix.png Screenshot from Atari 8-bit computer]
<pre>
Matrix size: 5
0 1 5 6 14
2 4 7 13 15
3 8 12 16 21
9 11 17 20 22
10 18 19 23 24
 
Matrix size: 6
0 1 5 6 14 15
2 4 7 13 16 25
3 8 12 17 24 26
9 11 18 23 27 32
10 19 22 28 31 33
20 21 29 30 34 35
</pre>
 
=={{header|ActionScript}}==
<syntaxhighlight lang="as">
<lang as>
package
{
Line 49 ⟶ 270:
}
}
}</syntaxhighlight>
}
 
</lang>
=={{header|Ada}}==
<langsyntaxhighlight lang="ada">with Ada.Text_IO; use Ada.Text_IO;
 
procedure Test_Zig_Zag is
Line 101 ⟶ 322:
begin
Put (Zig_Zag (5));
end Test_Zig_Zag;</langsyntaxhighlight>
The function Zig_Zag generates a square matrix filled as requested by the task.
 
{{out}}
Sample output:
<pre>
0 1 5 6 14
Line 111 ⟶ 332:
9 11 17 20 22
10 18 19 23 24
</pre>
 
=={{header|Agena}}==
Tested with Agena 2.9.5 Win32
<syntaxhighlight lang="agena"># zig-zag matrix
 
makeZigZag := proc( n :: number ) :: table is
 
local move := proc( x :: number, y :: number, upRight :: boolean ) is
if y = n then
upRight := not upRight;
x := x + 1
elif x = 1 then
upRight := not upRight;
y := y + 1
else
x := x - 1;
y := y + 1
fi;
return x, y, upRight
end ;
 
# create empty table
local result := [];
for i to n do
result[ i ] := [];
for j to n do result[ i, j ] := 0 od
od;
 
# fill the table
local x, y, upRight := 1, 1, true;
for i to n * n do
result[ x, y ] := i - 1;
if upRight then
x, y, upRight := move( x, y, upRight )
else
y, x, upRight := move( y, x, upRight )
fi
od;
 
return result
end;
 
scope
local m := makeZigZag( 5 );
for i to size m do
for j to size m do
printf( " %3d", m[ i, j ] )
od;
print()
od
epocs</syntaxhighlight>
{{out}}
<pre>
0 1 5 6 14
2 4 7 13 15
3 8 12 16 21
9 11 17 20 22
10 18 19 23 24
</pre>
 
Line 121 ⟶ 401:
 
{{works with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release 1.8.8d.fc9.i386}}
<syntaxhighlight lang ="algol68">PROC zig zag = (INT n)[,]INT: (
PROC zig zag = (INT n)[,]INT: (
PROC move = (REF INT i, j)VOID: (
IF j < n THEN
Line 155 ⟶ 436:
[,]INT result = zig zag(dim);
FOR i TO dim DO
print((result[IF i,], new= 1 THEN "((" ELSE " (" lineFI));
FOR j TO dim DO
print(( whole( result[i,j], -3 ), IF j /= dim THEN "," ELSE "" FI ))
OD;
print((IF i = dim THEN "))" ELSE ")," FI, new line))
OD
#FI#</lang>
</syntaxhighlight>
Sample output:
{{out}}
{|border="1" style="border-collapse: collapse; border: 5px double grey;"
<pre>
|align=center width=50%| With formatted transput possible, e.g. [[ALGOL 68G]]
|align=center| '''not''' formatted transput possible, e.g. [[ELLA ALGOL 68]]
|-
|align=center|<pre>
(( 0, 1, 5, 6, 14),
( 2, 4, 7, 13, 15),
Line 170 ⟶ 452:
( 10, 18, 19, 23, 24))
</pre>
 
||<pre>
=={{header|ALGOL W}}==
+0 +1 +5 +6 +14
Based on the Agena sample.
+2 +4 +7 +13 +15
<syntaxhighlight lang="algolw">begin % zig-zag matrix %
+3 +8 +12 +16 +21
% z is returned holding a zig-zag matrix of order n, z must be at least n x n %
+9 +11 +17 +20 +22
procedure makeZigZag ( integer value n
+10 +18 +19 +23 +24
; integer array z( *, * )
) ;
begin
procedure move ;
begin
if y = n then begin
upRight := not upRight;
x := x + 1
end
else if x = 1 then begin
upRight := not upRight;
y := y + 1
end
else begin
x := x - 1;
y := y + 1
end
end move ;
procedure swapXY ;
begin
integer swap;
swap := x;
x := y;
y := swap;
end swapXY ;
integer x, y;
logical upRight;
% initialise the n x n matrix in z %
for i := 1 until n do for j := 1 until n do z( i, j ) := 0;
% fill in the zig-zag matrix %
x := y := 1;
upRight := true;
for i := 1 until n * n do begin
z( x, y ) := i - 1;
if upRight then move
else begin
swapXY;
move;
swapXY
end;
end;
end makeZigZap ;
begin
integer array zigZag( 1 :: 10, 1 :: 10 );
for n := 5 do begin
makeZigZag( n, zigZag );
for i := 1 until n do begin
write( i_w := 4, s_w := 1, zigZag( i, 1 ) );
for j := 2 until n do writeon( i_w := 4, s_w := 1, zigZag( i, j ) );
end
end
end
 
end.</syntaxhighlight>
{{out}}
<pre>
0 1 5 6 14
2 4 7 13 15
3 8 12 16 21
9 11 17 20 22
10 18 19 23 24
</pre>
|}
 
=={{header|APL}}==
Line 183 ⟶ 526:
 
{{trans|J}}
<langsyntaxhighlight lang="apl"> zz ← {⍵⍴⎕IO-⍨⍋⊃,/{(2|⍴⍵):⌽⍵⋄⍵}¨(⊂w)/¨⍨w{↓⍵∘.=⍨∪⍵}+/[1]⍵⊤w←⎕IO-⍨⍳×/⍵} ⍝ General zigzag (any rectangle)
zzSq ← {zz,⍨⍵} ⍝ Square zigzag
zzSq 5
Line 190 ⟶ 533:
3 8 12 16 21
9 11 17 20 22
10 18 19 23 24</langsyntaxhighlight>
 
=={{header|AppleScript}}==
 
===Iterative===
 
Here's a vector & matrix boundary detection approach to the Zig-zap matrix:
<langsyntaxhighlight AppleScriptlang="applescript">set n to 5 -- Size of zig-zag matrix (n^2 cells).
 
-- Create an empty matrix.
Line 230 ⟶ 576:
set end of i to return
end repeat
return return & m as string</langsyntaxhighlight>
But this can be improved upon by building the matrix by populating empty AppleScript lists (it's about 50% faster when n=50):<langsyntaxhighlight AppleScriptlang="applescript">set n to 5
 
set m to {}
Line 264 ⟶ 610:
set i's contents to (i as string) & return
end repeat
return return & m as string</syntaxhighlight>
</lang>Output{{out}} for both scripts is:<lang AppleScriptpre>"
0 1 5 6 14
2 4 7 13 15
Line 271 ⟶ 617:
9 11 17 20 22
10 18 19 23 24
"</langpre>
 
 
===Recursive===
By functional composition:
<syntaxhighlight lang="applescript">-- zigzagMatrix
on zigzagMatrix(n)
-- diagonals :: n -> [[n]]
script diagonals
on |λ|(n)
script mf
on diags(xs, iCol, iRow)
if (iCol < length of xs) then
if iRow < n then
set iNext to iCol + 1
else
set iNext to iCol - 1
end if
set {headList, tail} to splitAt(iCol, xs)
{headList} & diags(tail, iNext, iRow + 1)
else
{xs}
end if
end diags
end script
diags(enumFromTo(0, n * n - 1), 1, 1) of mf
end |λ|
end script
-- oddReversed :: [a] -> Int -> [a]
script oddReversed
on |λ|(lst, i)
if i mod 2 = 0 then
lst
else
reverse of lst
end if
end |λ|
end script
rowsFromDiagonals(n, map(oddReversed, |λ|(n) of diagonals))
end zigzagMatrix
 
-- Rows of given length from list of diagonals
-- rowsFromDiagonals :: Int -> [[a]] -> [[a]]
on rowsFromDiagonals(n, lst)
if length of lst > 0 then
-- lengthOverOne :: [a] -> Bool
script lengthOverOne
on |λ|(lst)
length of lst > 1
end |λ|
end script
set {edge, residue} to splitAt(n, lst)
{map(my head, edge)} & ¬
rowsFromDiagonals(n, ¬
map(my tail, ¬
filter(lengthOverOne, edge)) & residue)
else
{}
end if
end rowsFromDiagonals
 
 
-- TEST -----------------------------------------------------------------------
on run
zigzagMatrix(5)
end run
 
 
-- GENERIC FUNCTIONS ----------------------------------------------------------
 
-- enumFromTo :: Int -> Int -> [Int]
on enumFromTo(m, n)
if n < m then
set d to -1
else
set d to 1
end if
set lst to {}
repeat with i from m to n by d
set end of lst to i
end repeat
return lst
end enumFromTo
 
-- filter :: (a -> Bool) -> [a] -> [a]
on filter(f, xs)
tell mReturn(f)
set lst to {}
set lng to length of xs
repeat with i from 1 to lng
set v to item i of xs
if |λ|(v, i, xs) then set end of lst to v
end repeat
return lst
end tell
end filter
 
-- head :: [a] -> a
on head(xs)
if length of xs > 0 then
item 1 of xs
else
missing value
end if
end head
 
-- 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
 
-- Lift 2nd class handler function into 1st class script wrapper
-- mReturn :: Handler -> Script
on mReturn(f)
if class of f is script then
f
else
script
property |λ| : f
end script
end if
end mReturn
 
-- splitAt:: n -> list -> {n items from start of list, rest of list}
-- splitAt :: Int -> [a] -> ([a], [a])
on splitAt(n, xs)
if n > 0 and n < length of xs then
{items 1 thru n of xs, items (n + 1) thru -1 of xs}
else
if n < 1 then
{{}, xs}
else
{xs, {}}
end if
end if
end splitAt
 
-- tail :: [a] -> [a]
on tail(xs)
if length of xs > 1 then
items 2 thru -1 of xs
else
{}
end if
end tail</syntaxhighlight>
{{Out}}
<pre>{{0, 1, 5, 6, 14},
{2, 4, 7, 13, 15},
{3, 8, 12, 16, 21},
{9, 11, 17, 20, 22},
{10, 18, 19, 23, 24}}</pre>
----
===Optimised iterative===
This is an optimised version of the second iterative script above, with the rendition to text kept separate and corrected. With n = 50, it's about 7.6 times as fast as the script on which it's based.
 
<syntaxhighlight lang="applescript">on zigzagMatrix(n)
script o
property matrix : {} -- Matrix list.
property row : missing value -- Row sublist.
end script
repeat n times
set end of o's matrix to {} -- Build a foundation for the matrix out of n empty lists.
end repeat
set {r, d} to {1, -1} -- Row index and direction to next insertion row (negative = row above).
repeat with v from 0 to (n ^ 2) - 1 -- Values to insert.
set o's row to o's matrix's item r
repeat while ((count o's row) = n)
set r to r + 1
set d to 1
set o's row to o's matrix's item r
end repeat
set end of o's row to v
set r to r + d
if (r < 1) then
set r to 1
set d to -d
else if (r > n) then
set r to n
set d to -d
else if ((r > 1) and ((count o's matrix's item (r - 1)) = 1)) then
set d to -d
end if
end repeat
return o's matrix
end zigzagMatrix
 
-- Demo:
on matrixToText(matrix, w)
script o
property matrix : missing value
property row : missing value
end script
set o's matrix to matrix
set padding to " "
repeat with r from 1 to (count o's matrix)
set o's row to o's matrix's item r
repeat with i from 1 to (count o's row)
set o's row's item i to text -w thru end of (padding & o's row's item i)
end repeat
set o's matrix's item r to join(o's row, "")
end repeat
return join(o's matrix, linefeed)
end matrixToText
 
on join(lst, delim)
set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to delim
set txt to lst as text
set AppleScript's text item delimiters to astid
return txt
end join
 
set n to 5
set matrix to zigzagMatrix(n)
linefeed & matrixToText(matrix, (count (n ^ 2 - 1 as integer as text)) + 2) & linefeed</syntaxhighlight>
 
{{output}}
<pre>
0 1 5 6 14
2 4 7 13 15
3 8 12 16 21
9 11 17 20 22
10 18 19 23 24
</pre>
 
=={{header|Applesoft BASIC}}==
<syntaxhighlight lang="applesoftbasic">100 S = 5
110 S2 = S ^ 2 : REM SQUARED
120 H = S2 / 2 : REM HALFWAY
130 S2 = S2 - 1
140 DX = 1 : REM INITIAL
150 DY = 0 : REM DIRECTION
160 N = S - 1
170 DIM A%(N, N)
 
200 FOR I = 0 TO H
210 A%(X, Y) = I
220 A%(N - X, N - Y) = S2 - I
230 X = X + DX
240 Y = Y + DY
250 IF Y = 0 THEN DY = DY + 1 : IF DY THEN DX = -DX
260 IF X = 0 THEN DX = DX + 1 : IF DX THEN DY = -DY
270 NEXT I
 
300 FOR Y = 0 TO N
310 FOR X = 0 TO N
320 IF X THEN PRINT TAB(X * (LEN(STR$(S2)) + 1) + 1);
330 PRINT A%(X, Y);
340 NEXT X
350 PRINT
360 NEXT Y</syntaxhighlight>
 
=={{header|Arturo}}==
 
<syntaxhighlight lang="rebol">zigzag: function [n][
result: map 1..n 'x -> map 1..n => 0
 
x: 1, y: 1, v: 0, d: 1
 
while [v < n^2][
if? all? @[1 =< x x =< n 1 =< y y =< n][
set get result (y-1) (x-1) v
x: x + d, y: y - d, v: v + 1
]
else[if? x > n [x: n, y: y + 2, d: neg d]
else[if? y > n [x: x + 2, y: n, d: neg d]
else[if? x < 1 [x: 1, d: neg d]
else[if y < 1 [y: 1, d: neg d]
]
]
]
]
]
result
]
 
zz: zigzag 5
loop zz 'row -> print map row 'col [pad to :string col 3]</syntaxhighlight>
 
{{out}}
 
<pre> 0 1 5 6 14
2 4 7 13 15
3 8 12 16 21
9 11 17 20 22
10 18 19 23 24</pre>
 
=={{header|ATS}}==
<syntaxhighlight lang="ats">
(* ****** ****** *)
//
#include
"share/atspre_define.hats" // defines some names
#include
"share/atspre_staload.hats" // for targeting C
#include
"share/HATS/atspre_staload_libats_ML.hats" // for ...
//
(* ****** ****** *)
//
extern
fun
Zig_zag_matrix(n: int): void
//
(* ****** ****** *)
 
fun max(a: int, b: int): int =
if a > b then a else b
 
fun movex(n: int, x: int, y: int): int =
if y < n-1 then max(0, x-1) else x+1
 
fun movey(n: int, x: int, y: int): int =
if y < n-1 then y+1 else y
 
fun zigzag(n: int, i: int, row: int, x: int, y: int): void =
if i = n*n then ()
else
let
val () = (if x = row then begin print i; print ','; end else ())
//val () = (begin print x; print ' '; print y; print ' '; print i; print ' '; end)
val nextX: int = if ((x+y) % 2) = 0 then movex(n, x, y) else movey(n, y, x)
val nextY: int = if ((x+y) % 2) = 0 then movey(n, x, y) else movex(n, y, x)
in
zigzag(n, i+1, row, nextX, nextY)
end
 
implement
Zig_zag_matrix(n) =
let
fun loop(row: int): void =
if row = n then () else
let
val () = zigzag(n, 0, row, 0, 0)
val () = println!(" ")
in
loop(row + 1)
end
in
loop(0)
end
 
(* ****** ****** *)
 
implement
main0() = () where
{
val () = Zig_zag_matrix(5)
} (* end of [main0] *)
 
(* ****** ****** *)
</syntaxhighlight>
 
=={{header|AutoHotkey}}==
{{trans|lisp}} <br>
contributed by Laszlo on the ahk [http://www.autohotkey.com/forum/post-276307.html#276307 forum].
<langsyntaxhighlight AutoHotkeylang="autohotkey">n = 5 ; size
v := x := y := 1 ; initial values
Loop % n*n { ; for every array element
Line 296 ⟶ 1,016:
t .= "`n" ; row is complete
}
MsgBox %t% ; show output</langsyntaxhighlight>
 
=={{header|AutoIt}}==
<syntaxhighlight lang="autoit">
#include <Array.au3>
$Array = ZigZag(5)
_ArrayDisplay($Array)
 
Func ZigZag($int)
Local $av_array[$int][$int]
Local $x = 1, $y = 1
For $I = 0 To $int ^ 2 -1
$av_array[$x-1][$y-1] = $I
If Mod(($x + $y), 2) = 0 Then ;Even
if ($y < $int) Then
$y += 1
Else
$x += 2
EndIf
if ($x > 1) Then $x -= 1
Else ; ODD
if ($x < $int) Then
$x += 1
Else
$y += 2
EndIf
If $y > 1 Then $y -= 1
EndIf
Next
Return $av_array
EndFunc ;==>ZigZag</syntaxhighlight>
 
=={{header|AWK}}==
<syntaxhighlight lang="awk">
# syntax: GAWK -f ZIG-ZAG_MATRIX.AWK [-v offset={0|1}] [size]
BEGIN {
# offset: "0" prints 0 to size^2-1 while "1" prints 1 to size^2
offset = (offset == "") ? 0 : offset
size = (ARGV[1] == "") ? 5 : ARGV[1]
if (offset !~ /^[01]$/) { exit(1) }
if (size !~ /^[0-9]+$/) { exit(1) }
width = length(size ^ 2 - 1 + offset) + 1
i = j = 1
for (n=0; n<=size^2-1; n++) { # build array
arr[i-1,j-1] = n + offset
if ((i+j) % 2 == 0) {
if (j < size) { j++ } else { i+=2 }
if (i > 1) { i-- }
}
else {
if (i < size) { i++ } else { j+=2 }
if (j > 1) { j-- }
}
}
for (row=0; row<size; row++) { # show array
for (col=0; col<size; col++) {
printf("%*d",width,arr[row,col])
}
printf("\n")
}
exit(0)
}</syntaxhighlight>
{{out}}
<pre>
0 1 5 6 14
2 4 7 13 15
3 8 12 16 21
9 11 17 20 22
10 18 19 23 24
</pre>
 
=={{header|BBC BASIC}}==
<syntaxhighlight lang="bbcbasic"> Size% = 5
DIM array%(Size%-1,Size%-1)
i% = 1
j% = 1
FOR e% = 0 TO Size%^2-1
array%(i%-1,j%-1) = e%
IF ((i% + j%) AND 1) = 0 THEN
IF j% < Size% j% += 1 ELSE i% += 2
IF i% > 1 i% -= 1
ELSE
IF i% < Size% i% += 1 ELSE j% += 2
IF j% > 1 j% -= 1
ENDIF
NEXT
@% = &904
FOR row% = 0 TO Size%-1
FOR col% = 0 TO Size%-1
PRINT array%(row%,col%);
NEXT
PRINT
NEXT row%</syntaxhighlight>
{{out}}
<pre>
0 1 5 6 14
2 4 7 13 15
3 8 12 16 21
9 11 17 20 22
10 18 19 23 24
</pre>
 
=={{header|Beads}}==
This is a translation of the [[Zig-zag_matrix#C++|C++]] example.
<syntaxhighlight lang="beads">beads 1 program 'Zig-zag Matrix'
 
calc main_init
var test : array^2 of num = create_array(5)
printMatrix(test)
calc create_array(
dimension:num
):array^2 of num
var
result : array^2 of num
lastValue = dimension^2 - 1
loopFrom
loopTo
row
col
currDiag = 0
currNum = 0
loop
if (currDiag < dimension) // if doing the upper-left triangular half
loopFrom = 1
loopTo = currDiag + 1
else // doing the bottom-right triangular half
loopFrom = currDiag - dimension + 2
loopTo = dimension
loop count:c from:loopFrom to:loopTo
var i = loopFrom + c - 1
if (rem(currDiag, 2) == 0) // want to fill upwards
row = loopTo - i + loopFrom
col = i
else // want to fill downwards
row = i
col = loopTo - i + loopFrom
result[row][col] = currNum
inc currNum
inc currDiag
if (currNum > lastValue)
exit
return result
calc printMatrix(
matrix:array^2 of num
)
var dimension = tree_count(matrix)
var maxDigits = 1 + lg((dimension^2-1), base:10)
loop across:matrix ptr:rowp index:row
var tempstr : str
loop across:rowp index:col
tempstr = tempstr & " " & to_str(matrix[row][col], min:maxDigits)
log(tempstr)</syntaxhighlight>
{{out}}
<pre> 0 1 5 6 14
2 4 7 13 15
3 8 12 16 21
9 11 17 20 22
10 18 19 23 24</pre>
 
=={{header|Befunge}}==
The size, ''N'', is specified by the first value on the stack - 5 in the example below. The upper limit is constrained only by the range of the playfield cells used for variables, since we're using an algorithm that calculates the values on the fly rather than building them up in memory. On an 8 bit interpreter this means an upper limit of at least 127, but with an extended cell range the size of ''N'' can be almost unlimited.
 
<syntaxhighlight lang="befunge">>> 5 >>00p0010p:1:>20p030pv >0g-:0`*:*-:00g:*1-55+/>\55+/:v v:,*84<
v:++!\**2p01:+1g01:g02$$_>>#^4#00#+p#1:#+1#g0#0g#3<^/+ 55\_$:>55+/\|
>55+,20g!00g10g`>#^_$$$@^!`g03g00!g04++**2p03:+1g03!\*+1*2g01:g04.$<</syntaxhighlight>
 
{{out}}
<pre> 0 1 5 6 14
2 4 7 13 15
3 8 12 16 21
9 11 17 20 22
10 18 19 23 24</pre>
 
=={{header|BQN}}==
<syntaxhighlight lang="bqn">Flip ← {m←2|+⌜˜↕≠𝕩 ⋄ (⍉𝕩׬m)+𝕩×m}
Zz ← {Flip ⍋∘⍋⌾⥊+⌜˜↕𝕩}</syntaxhighlight>
 
Example:
 
<syntaxhighlight lang="bqn">Zz 5</syntaxhighlight>
 
<pre>
┌─
╵ 0 1 5 6 14
2 4 7 13 15
3 8 12 16 21
9 11 17 20 22
10 18 19 23 24
</pre>
 
([https://mlochbaum.github.io/BQN/try.html#code=RmxpcCDihpAge23ihpAyfCvijJzLnOKGleKJoPCdlakg4ouEICjijYnwnZWpw5fCrG0pK/CdlanDl219ClpaICAg4oaQIHtGbGlwIOKNi+KImOKNi+KMvuKliivijJzLnOKGlfCdlal9CgpaWiA1 online REPL])
 
=={{header|C}}==
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
Line 321 ⟶ 1,236:
/* free(s) */
return 0;
}</syntaxhighlight>
}</lang>output<lang>% ./a.out 7
{{out}}
<pre>% ./a.out 7
0 1 5 6 14 15 27
2 4 7 13 16 26 28
Line 328 ⟶ 1,245:
10 19 23 31 36 40 45
20 22 32 35 41 44 46
21 33 34 42 43 47 48</langpre>
 
=={{header|C sharp}}==
 
<syntaxhighlight lang="csharp">public static int[,] ZigZag(int n)
{
int[,] result = new int[n, n];
int i = 0, j = 0;
int d = -1; // -1 for top-right move, +1 for bottom-left move
int start = 0, end = n * n - 1;
do
{
result[i, j] = start++;
result[n - i - 1, n - j - 1] = end--;
 
i += d; j -= d;
if (i < 0)
{
i++; d = -d; // top reached, reverse
}
else if (j < 0)
{
j++; d = -d; // left reached, reverse
}
} while (start < end);
if (start == end)
result[i, j] = start;
return result;
}</syntaxhighlight>
 
=={{header|C++}}==
<langsyntaxhighlight lang="cpp">#include <vector>
#include <memory> // for auto_ptr
#include <cmath> // for the log10 and floor functions
Line 387 ⟶ 1,332:
currDiag++;
}
while ( currNumcurrDiag <= lastValue );
 
return zigZagArrayPtr;
Line 411 ⟶ 1,356:
{
printZigZagArray( getZigZagArray( 5 ) );
}</langsyntaxhighlight>
{{out}}
<pre>
0 1 5 6 14
2 4 7 13 15
3 8 12 16 21
9 11 17 20 22
10 18 19 23 24
</pre>
 
=={{header|C sharpCeylon}}==
<syntaxhighlight lang="ceylon">class ZigZag(Integer size) {
value data = Array {
for (i in 0:size)
Array.ofSize(size, 0)
};
variable value i = 1;
variable value j = 1;
for (element in 0 : size^2) {
data[j - 1]?.set(i - 1, element);
if ((i + j).even) {
if (j < size) {
j++;
}
else {
i += 2;
}
if (i > 1) {
i--;
}
}
else {
if (i < size) {
i++;
}
else {
j += 2;
}
if (j > 1) {
j--;
}
}
}
shared void display() {
for (row in data) {
for (element in row) {
process.write(element.string.pad(3));
}
print(""); //newline
}
}
}
 
shared void run() {
<lang csharp>public static int[,] ZigZag(int n)
value zz = ZigZag(5);
{
zz.display();
int[,] result = new int[n, n];
}</syntaxhighlight>
int i = 0, j = 0;
int d = -1; // -1 for top-right move, +1 for bottom-left move
int start = 0, end = n * n - 1;
do
{
result[i, j] = start++;
result[n - i - 1, n - j - 1] = end--;
 
i += d; j -= d;
if (i < 0)
{
i++; d = -d; // top reached, reverse
}
else if (j < 0)
{
j++; d = -d; // left reached, reverse
}
} while (start < end);
if (start == end)
result[i, j] = start;
return result;
}</lang>
 
=={{header|Clojure}}==
Purely functional approach.
<langsyntaxhighlight Clojurelang="clojure">(defn partitions [sizes coll]
(lazy-seq
(when-let [n (first sizes)]
Line 475 ⟶ 1,452:
( 9 11 18 23 27 32)
(10 19 22 28 31 33)
(20 21 29 30 34 35))</langsyntaxhighlight>
 
=={{header|CoffeeScript}}==
<syntaxhighlight lang="coffeescript">
# Calculate a zig-zag pattern of numbers like so:
# 0 1 5
# 2 4 6
# 3 7 8
#
# There are many interesting ways to solve this; we
# try for an algebraic approach, calculating triangle
# areas, so that me minimize space requirements.
 
zig_zag_value = (x, y, n) ->
 
upper_triangle_zig_zag = (x, y) ->
# calculate the area of the triangle from the prior
# diagonals
diag = x + y
triangle_area = diag * (diag+1) / 2
# then add the offset along the diagonal
if diag % 2 == 0
triangle_area + y
else
triangle_area + x
if x + y < n
upper_triangle_zig_zag x, y
else
# For the bottom right part of the matrix, we essentially
# use reflection to count backward.
bottom_right_cell = n * n - 1
n -= 1
v = upper_triangle_zig_zag(n-x, n-y)
bottom_right_cell - v
zig_zag_matrix = (n) ->
row = (i) -> (zig_zag_value i, j, n for j in [0...n])
(row i for i in [0...n])
 
do ->
for n in [4..6]
console.log "---- n=#{n}"
console.log zig_zag_matrix(n)
console.log "\n"</syntaxhighlight>
 
{{out}}
<pre>
> coffee zigzag.coffee
---- n=4
[ [ 0, 1, 5, 6 ],
[ 2, 4, 7, 12 ],
[ 3, 8, 11, 13 ],
[ 9, 10, 14, 15 ] ]
 
 
---- n=5
[ [ 0, 1, 5, 6, 14 ],
[ 2, 4, 7, 13, 15 ],
[ 3, 8, 12, 16, 21 ],
[ 9, 11, 17, 20, 22 ],
[ 10, 18, 19, 23, 24 ] ]
 
 
---- n=6
[ [ 0, 1, 5, 6, 14, 15 ],
[ 2, 4, 7, 13, 16, 25 ],
[ 3, 8, 12, 17, 24, 26 ],
[ 9, 11, 18, 23, 27, 32 ],
[ 10, 19, 22, 28, 31, 33 ],
[ 20, 21, 29, 30, 34, 35 ] ]
</pre>
 
=={{header|Common Lisp}}==
==={{trans|Java}} (but with zero-based indexes and combining the even and odd cases)===
<langsyntaxhighlight lang="lisp">(defun zigzag (n)
(flet ((move (i j)
(if (< j (1- n))
Line 492 ⟶ 1,540:
(setf (values x y) (move x y))
(setf (values y x) (move y x)))
finally (return a))))</langsyntaxhighlight>
 
===An alternative approach===
<syntaxhighlight lang="lisp">
; ZigZag
;
; Nigel Galloway.
; June 4th., 2012
;
(defun ZigZag (COLS)
(let ((cs 2) (st '(1 2)) (dx '(-1 1)))
(defun new_cx (i)
(setq st (append st (list (setq cs (+ cs (* 2 i))) (setq cs (+ 1 cs))))
dx (append dx '(-1 1))))
(do ((i 2 (+ 2 i))) ((>= i COLS)) (new_cx i))
(do ((i (- COLS 1 (mod COLS 2)) (+ -2 i))) ((<= i 0)) (new_cx i))
(do ((i 0 (+ 1 i))) ((>= i COLS))
(format t "~%")
(do ((j i (+ 1 j))) ((>= j (+ COLS i)))
(format t "~3d" (nth j st))
(setf (nth j st) (+ (nth j st) (nth j dx)))))))
</syntaxhighlight>
(ZigZag 5) Produces:
<pre>
1 2 6 7 15
3 5 8 14 16
4 9 13 17 22
10 12 18 21 23
11 19 20 24 25
</pre>
(ZigZag 8) Produces:
<pre>
1 2 6 7 15 16 28 29
3 5 8 14 17 27 30 43
4 9 13 18 26 31 42 44
10 12 19 25 32 41 45 54
11 20 24 33 40 46 53 55
21 23 34 39 47 52 56 61
22 35 38 48 51 57 60 62
36 37 49 50 58 59 63 64
</pre>
(ZigZag 9) Produces:
<pre>
1 2 6 7 15 16 28 29 45
3 5 8 14 17 27 30 44 46
4 9 13 18 26 31 43 47 60
10 12 19 25 32 42 48 59 61
11 20 24 33 41 49 58 62 71
21 23 34 40 50 57 63 70 72
22 35 39 51 56 64 69 73 78
36 38 52 55 65 68 74 77 79
37 53 54 66 67 75 76 80 81
</pre>
 
=={{header|Crystal}}==
{{trans|Ruby}}
<syntaxhighlight lang="ruby">def zigzag(n)
(seq=(0...n).to_a).product(seq)
.sort_by {|x,y| [x+y, (x+y).even? ? y : -y]}
.map_with_index{|v, i| {v, i}}.sort.map(&.last).each_slice(n).to_a
end
def print_matrix(m)
format = "%#{m.flatten.max.to_s.size}d " * m[0].size
m.each {|row| puts format % row}
end
print_matrix zigzag(5)</syntaxhighlight>
{{out}}
<pre>
0 1 5 6 14
2 4 7 13 15
3 8 12 16 21
9 11 17 20 22
10 18 19 23 24
</pre>
 
=={{header|D}}==
{{trans|Common Lisp}}
<syntaxhighlight lang="d">int[][] zigZag(in int n) pure nothrow @safe {
<lang d>import std.stdio;
static void move(in int n, ref int i, ref int j)
 
pure nothrow @safe @nogc {
pure nothrow int[][] zigzag(in int n) {
pure nothrow void move(in int n, ref int i, ref int j) {
if (j < n - 1) {
if (i > 0) i--;
Line 507 ⟶ 1,629:
}
 
int x, y;
auto a = new int[][](n, n);
int x, y;
foreach (v; 0 .. n * n) {
foreach (v; 0 .. n ^^ 2) {
a[y][x] = v;
(x + y) % 2 ? move(n, x, y) : move(n, y, x);
Line 517 ⟶ 1,639:
 
void main() {
import std.stdio;
foreach (row; zigzag(5)) {
 
foreach (n; row)
writefwritefln("%3d(%(%2d %)\n%)", n5.zigZag);
}</syntaxhighlight>
writeln();
{{out}}
}
<pre> 0 1 5 6 14
}</lang>
2 4 7 13 15
Output:
<pre> 3 08 12 116 5 6 1421
9 11 17 20 22
2 4 7 13 15
10 18 19 23 24</pre>
3 8 12 16 21
 
9 11 17 20 22
===Alternative Version===
10 18 19 23 24</pre>
{{trans|Scala}}
Same output.
<syntaxhighlight lang="d">import std.stdio, std.algorithm, std.range, std.array;
 
int[][] zigZag(in int n) pure nothrow {
static struct P2 { int x, y; }
const L = iota(n ^^ 2).map!(i => P2(i % n, i / n)).array
.sort!q{ (a.x + a.y == b.x + b.y) ?
((a.x + a.y) % 2 ? a.y < b.y : a.x < b.x) :
(a.x + a.y) < (b.x + b.y) }.release;
 
auto result = new typeof(return)(n, n);
foreach (immutable i, immutable p; L)
result[p.y][p.x] = i;
return result;
}
 
void main() {
writefln("%(%(%2d %)\n%)", 5.zigZag);
}</syntaxhighlight>
 
=={{header|E}}==
Line 536 ⟶ 1,678:
 
Then the code. {{trans|D}}
<langsyntaxhighlight lang="e">def zigZag(n) {
def move(&i, &j) {
if (j < (n - 1)) {
Line 559 ⟶ 1,701:
}
return array
}</langsyntaxhighlight>
 
=={{header|Delphi}}==
{{works with|Delphi|6.0}}
{{libheader|SysUtils,StdCtrls}}
 
 
<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 ZigzagMatrix(Memo: TMemo);
var Mat: TMatrix;
var X,Y,Inx,Dir: integer;
const Size = 10;
 
procedure Toggle(var I: integer);
{Toggle Direction and increment I}
begin
Dir:=-Dir;
Inc(I);
end;
 
 
procedure Step(var X,Y: integer);
{Take one step "Dir" direction}
begin
X:=X+Dir;
Y:=Y-Dir;
end;
 
begin
SetLength(Mat,Size,Size);
Inx:=0; X:=0; Y:=0; Dir:=1;
repeat
begin
Mat[X,Y]:=Inx;
if (X+Dir)>=Size then Toggle(Y)
else if (Y-Dir)>=Size then Toggle(X)
else if (X+Dir)<0 then Toggle(Y)
else if (Y-Dir)<0 then Toggle(X)
else Step(X,Y);
Inc(Inx);
end
until Inx>=Size*Size;
DisplayMatrix(Memo,Mat);
end;
</syntaxhighlight>
{{out}}
<pre>
[ 0 1 5 6 14 15 27 28 44 45]
[ 2 4 7 13 16 26 29 43 46 63]
[ 3 8 12 17 25 30 42 47 62 64]
[ 9 11 18 24 31 41 48 61 65 78]
[ 10 19 23 32 40 49 60 66 77 79]
[ 20 22 33 39 50 59 67 76 80 89]
[ 21 34 38 51 58 68 75 81 88 90]
[ 35 37 52 57 69 74 82 87 91 96]
[ 36 53 56 70 73 83 86 92 95 97]
[ 54 55 71 72 84 85 93 94 98 99]
 
 
Elapsed Time: 1.576 ms.
 
</pre>
 
 
=={{header|Elena}}==
{{trans|C#}}
ELENA 5.0:
<syntaxhighlight lang="elena">import extensions;
extension op : IntNumber
{
zigzagMatrix()
{
auto result := IntMatrix.allocate(self, self);
int i := 0;
int j := 0;
int d := -1;
int start := 0;
int end := self*self - 1;
while (start < end)
{
result.setAt(i, j, start); start += 1;
result.setAt(self - i - 1, self - j - 1, end); end -= 1;
i := i + d;
j := j - d;
if (i < 0)
{
i:=i+1; d := d.Negative
}
else if (j < 0)
{
j := j + 1; d := d.Negative
}
};
if (start == end)
{
result.setAt(i, j, start)
};
^ result
}
}
public program()
{
console.printLine(5.zigzagMatrix()).readChar()
}</syntaxhighlight>
 
=={{header|Elixir}}==
<syntaxhighlight lang="elixir">defmodule RC do
require Integer
def zigzag(n) do
fmt = "~#{to_char_list(n*n-1) |> length}w "
(for x <- 1..n, y <- 1..n, do: {x,y})
|> Enum.sort_by(fn{x,y}->{x+y, if(Integer.is_even(x+y), do: y, else: x)} end)
|> Enum.with_index |> Enum.sort
|> Enum.each(fn {{_x,y},i} ->
:io.format fmt, [i]
if y==n, do: IO.puts ""
end)
end
end
 
RC.zigzag(5)</syntaxhighlight>
 
{{out}}
<pre>
0 1 5 6 14
2 4 7 13 15
3 8 12 16 21
9 11 17 20 22
10 18 19 23 24
</pre>
 
=={{header|EMal}}==
<syntaxhighlight lang="emal">
fun zigzag = List by int n
List matrix = List[].with(n)
for int y = 0; y < n; y++ do matrix[y] = int[].with(n) end
int y, x = 1
for int value = 0; value < n * n; value++
matrix[y - 1][x - 1] = value
if (y + x) % 2 == 0
if x < n do x++
else do y += 2 end
if y > 1 do y-- end
else
if y < n do y++
else do x += 2 end
if x > 1 do x-- end
end
end
return matrix
end
fun dump = void by List matrix
int max = length(text!(matrix.length ** 2)) + 1
for each List row in matrix
for each int value in row
write(" " * (max - length(text!value)) + value)
end
writeLine()
end
end
dump(zigzag(5))
writeLine()
dump(zigzag(10))
</syntaxhighlight>
{{out}}
<pre>
0 1 5 6 14
2 4 7 13 15
3 8 12 16 21
9 11 17 20 22
10 18 19 23 24
 
0 1 5 6 14 15 27 28 44 45
2 4 7 13 16 26 29 43 46 63
3 8 12 17 25 30 42 47 62 64
9 11 18 24 31 41 48 61 65 78
10 19 23 32 40 49 60 66 77 79
20 22 33 39 50 59 67 76 80 89
21 34 38 51 58 68 75 81 88 90
35 37 52 57 69 74 82 87 91 96
36 53 56 70 73 83 86 92 95 97
54 55 71 72 84 85 93 94 98 99
</pre>
 
=={{header|Erlang}}==
<syntaxhighlight lang="erlang">
-module( zigzag ).
 
-export( [matrix/1, task/0] ).
 
matrix( N ) ->
{{_X_Y, N}, Proplist} = lists:foldl( fun matrix_as_proplist/2, {{{0, 0}, N}, []}, lists:seq(0, (N * N) - 1) ),
[columns( X, Proplist ) || X <- lists:seq(0, N - 1)].
 
task() -> matrix( 5 ).
 
 
 
columns( Column, Proplist ) -> lists:sort( [Value || {{_X, Y}, Value} <- Proplist, Y =:= Column] ).
 
matrix_as_proplist( N, {{X_Y, Max}, Acc} ) ->
Next = next_indexes( X_Y, Max ),
{{Next, Max}, [{X_Y, N} | Acc]}.
 
next_indexes( {X, Y}, Max ) when Y + 1 =:= Max, (X + Y) rem 2 =:= 0 -> {X + 1, Y - 1};
next_indexes( {X, Y}, Max ) when Y + 1 =:= Max, (X + Y) rem 2 =:= 1 -> {X + 1, Y};
next_indexes( {X, Y}, Max ) when X + 1 =:= Max, (X + Y) rem 2 =:= 0 -> {X, Y + 1};
next_indexes( {X, Y}, Max ) when X + 1 =:= Max, (X + Y) rem 2 =:= 1 -> {X - 1, Y + 1};
next_indexes( {X, 0}, _Max ) when X rem 2 =:= 0 -> {X + 1, 0};
next_indexes( {X, 0}, _Max ) when X rem 2 =:= 1 -> {X - 1, 1};
next_indexes( {0, Y}, _Max ) when Y rem 2 =:= 0 -> {1, Y - 1};
next_indexes( {0, Y}, _Max ) when Y rem 2 =:= 1 -> {0, Y + 1};
next_indexes( {X, Y}, _Max ) when (X + Y) rem 2 =:= 0 -> {X + 1, Y - 1};
next_indexes( {X, Y}, _Max ) when (X + Y) rem 2 =:= 1 -> {X - 1, Y + 1}.</syntaxhighlight>
{{out}}
<pre>
71> zigzag:task().
[[0,1,5,6,14],
[2,4,7,13,15],
[3,8,12,16,21],
[9,11,17,20,22],
[10,18,19,23,24]]
</pre>
 
=={{header|ERRE}}==
<syntaxhighlight lang="erre">PROGRAM ZIG_ZAG
 
!$DYNAMIC
DIM ARRAY%[0,0]
 
BEGIN
SIZE%=5
!$DIM ARRAY%[SIZE%-1,SIZE%-1]
 
I%=1
J%=1
FOR E%=0 TO SIZE%^2-1 DO
ARRAY%[I%-1,J%-1]=E%
IF ((I%+J%) AND 1)=0 THEN
IF J%<SIZE% THEN J%+=1 ELSE I%+=2 END IF
IF I%>1 THEN I%-=1 END IF
ELSE
IF I%<SIZE% THEN I%+=1 ELSE J%+=2 END IF
IF J%>1 THEN J%-=1 END IF
END IF
END FOR
 
FOR ROW%=0 TO SIZE%-1 DO
FOR COL%=0 TO SIZE%-1 DO
WRITE("###";ARRAY%[ROW%,COL%];)
END FOR
PRINT
END FOR
END PROGRAM</syntaxhighlight>
{{out}}
<pre> 0 1 5 6 14
2 4 7 13 15
3 8 12 16 21
9 11 17 20 22
10 18 19 23 24</pre>
 
=={{header|Euphoria}}==
{{trans|C#}}
<langsyntaxhighlight Euphorialang="euphoria">function zigzag(integer size)
sequence s
integer i, j, d, max
Line 582 ⟶ 2,012:
end function
 
? zigzag(5)</langsyntaxhighlight>
{{out}}
 
Output:
{
{1,2,6,7,15},
Line 592 ⟶ 2,021:
{11,19,20,24,25}
}
 
=={{header|F_Sharp|F#}}==
<syntaxhighlight lang="fsharp">
//Produce a zig zag matrix - Nigel Galloway: April 7th., 2015
let zz l a =
let N = Array2D.create l a 0
let rec gng (n, i, g, e) =
N.[n,i] <- g
match e with
| _ when i=a-1 && n=l-1 -> N
| 1 when n = l-1 -> gng (n, i+1, g+1, 2)
| 2 when i = a-1 -> gng (n+1, i, g+1, 1)
| 1 when i = 0 -> gng (n+1, 0, g+1, 2)
| 2 when n = 0 -> gng (0, i+1, g+1, 1)
| 1 -> gng (n+1, i-1, g+1, 1)
| _ -> gng (n-1, i+1, g+1, 2)
gng (0, 0, 0, 2)
</syntaxhighlight>
{{out}}
<syntaxhighlight lang="fsharp">zz 5 5</syntaxhighlight>
<pre>
[[0; 1; 5; 6; 14]
[2; 4; 7; 13; 15]
[3; 8; 12; 16; 21]
[9; 11; 17; 20; 22]
[10; 18; 19; 23; 24]]
</pre>
<syntaxhighlight lang="fsharp">zz 8 8</syntaxhighlight>
<pre>
[[0; 1; 5; 6; 14; 15; 27; 28]
[2; 4; 7; 13; 16; 26; 29; 42]
[3; 8; 12; 17; 25; 30; 41; 43]
[9; 11; 18; 24; 31; 40; 44; 53]
[10; 19; 23; 32; 39; 45; 52; 54]
[20; 22; 33; 38; 46; 51; 55; 60]
[21; 34; 37; 47; 50; 56; 59; 61]
[35; 36; 48; 49; 57; 58; 62; 63]]
</pre>
Let's try something a little less square man
<syntaxhighlight lang="fsharp">zz 5 8</syntaxhighlight>
<pre>
[[0; 1; 5; 6; 14; 15; 24; 25]
[2; 4; 7; 13; 16; 23; 26; 33]
[3; 8; 12; 17; 22; 27; 32; 34]
[9; 11; 18; 21; 28; 31; 35; 38]
[10; 19; 20; 29; 30; 36; 37; 39]]
</pre>
 
=={{header|Factor}}==
This version follows the algorithm laid out in the comments of the first JavaScript (ES5) functional example, though it is not exactly a straight translation.
{{works with|Factor|0.99 2019-03-17}}
<syntaxhighlight lang="factor">USING: columns fry kernel make math math.ranges prettyprint
sequences sequences.cords sequences.extras ;
IN: rosetta-code.zig-zag-matrix
 
: [1,b,1] ( n -- seq )
[1,b] dup but-last-slice <reversed> cord-append ;
 
: <reversed-evens> ( seq -- seq' )
[ even? [ <reversed> ] when ] map-index ;
 
: diagonals ( n -- seq )
[ sq <iota> ] [ [1,b,1] ] bi
[ [ cut [ , ] dip ] each ] { } make nip <reversed-evens> ;
 
: zig-zag-matrix ( n -- seq )
[ diagonals ] [ dup ] bi '[
[
dup 0 <column> _ head ,
[ _ < [ rest-slice ] when ] map-index harvest
] until-empty
] { } make ;
 
: zig-zag-demo ( -- ) 5 zig-zag-matrix simple-table. ;
 
MAIN: zig-zag-demo</syntaxhighlight>
{{out}}
<pre>
0 1 5 6 14
2 4 7 13 15
3 8 12 16 21
9 11 17 20 22
10 18 19 23 24
</pre>
The following example is an implementation of a J routine with an [http://rosettacode.org/wiki/Talk:Zig-zag_matrix#reading_the_J_examples excellent walkthrough on the talk page]. Luckily, we can mimic the "classification" step with the composition of 3 existing Factor words: <code>zip-index expand-keys-push-at values</code> and the <code>inverse-permutation</code> word is the same concept as J's grade, so this is fairly succinct.
{{works with|Factor|0.99 2020-01-23}}
<syntaxhighlight lang="factor">USING: assocs assocs.extras grouping io kernel math
math.combinatorics math.matrices prettyprint sequences ;
 
: <zig-zag-matrix> ( n -- matrix )
[
dup [ + ] <matrix-by-indices> concat zip-index
expand-keys-push-at values [ even? [ reverse ] when ]
map-index concat inverse-permutation
] [ group ] bi ;
 
5 <zig-zag-matrix> simple-table.</syntaxhighlight>
{{out}}
<pre>
0 1 5 6 14
2 4 7 13 15
3 8 12 16 21
9 11 17 20 22
10 18 19 23 24
</pre>
 
=={{header|Fan}}==
<langsyntaxhighlight Fanlang="fan">using gfx // for Point; convenient x/y wrapper
 
**
Line 684 ⟶ 2,218:
print(zag(8))
}
}</langsyntaxhighlight>
 
=={{header|Forth}}==
<langsyntaxhighlight lang="forth">0 value diag
 
: south diag abs + cell+ ;
Line 736 ⟶ 2,270:
3 8 12 16 21
9 11 17 20 22
10 18 19 23 24 ok</langsyntaxhighlight>
 
 
=={{header|Fortran}}==
{{works with|Fortran|90 and later}}
<langsyntaxhighlight lang="fortran">PROGRAM ZIGZAG
IMPLICIT NONE
Line 778 ⟶ 2,311:
END DO
END PROGRAM ZIGZAG</langsyntaxhighlight>
 
=={{header|FreeBASIC}}==
<syntaxhighlight lang="freebasic">' FB 1.05.0 Win64
 
Dim As Integer n
 
Do
Input "Enter size of matrix "; n
Loop Until n > 0
 
Dim zigzag(1 To n, 1 To n) As Integer '' all zero by default
 
' enter the numbers 0 to (n^2 - 1) in the matrix's anti-diagonals
zigzag(1, 1) = 0
If n > 1 Then
Dim As Integer row = 0, col = 3
Dim As Boolean down = true, increment = true
Dim As Integer i = 0, j = 2, k
Do
If down Then
For k = 1 To j
i += 1
row += 1
col -= 1
zigzag(row, col) = i
Next
down = false
Else
For k = 1 To j
i += 1
row -= 1
col += 1
zigzag(row, col) = i
Next
down = true
End If
If increment Then
j += 1
If j > n Then
j = n - 1
increment = false
End If
Else
j -= 1
If j = 0 Then Exit Do
End If
If down AndAlso increment Then
col += 2
row -= 1
ElseIf Not Down AndAlso increment Then
row += 2
col -= 1
ElseIf down AndAlso Not increment Then
col += 1
Else '' Not down AndAlso NotIncrement
row += 1
End If
Loop
End If
 
' print zigzag 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 "####"; zigzag(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 ? 8
 
0 1 5 6 14 15 27 28
2 4 7 13 16 26 29 42
3 8 12 17 25 30 41 43
9 11 18 24 31 40 44 53
10 19 23 32 39 45 52 54
20 22 33 38 46 51 55 60
21 34 37 47 50 56 59 61
35 36 48 49 57 58 62 63
</pre>
 
=={{header|GAP}}==
<langsyntaxhighlight lang="gap">ZigZag := function(n)
local a, i, j, k;
a := NullMat(n, n);
Line 815 ⟶ 2,439:
# [ 3, 8, 12, 16, 21 ],
# [ 9, 11, 17, 20, 22 ],
# [ 10, 18, 19, 23, 24 ] ]</langsyntaxhighlight>
 
=={{header|Go}}==
{{trans|Groovy}} Edge direct algorithm
<langsyntaxhighlight lang="go">package main
 
import (
Line 864 ⟶ 2,489:
}
}
}</langsyntaxhighlight>
{{out}}
Output:
<pre>
0 1 5 6 14
Line 877 ⟶ 2,502:
 
=== Edge ===
An odd technique that traverses the grid edges directly and calculates the transform onto the grid.
and calculates the transform onto the grid.
 
<langsyntaxhighlight lang="groovy">def zz = { n ->
grid = new int[n][n]
i = 0
Line 889 ⟶ 2,515:
}
grid
}</langsyntaxhighlight>
 
Output
 
{{out}}
<pre>
> zz(5).each { it.each { print("${it}".padLeft(3)) }; println() }
0 1 5 6 14
Line 899 ⟶ 2,525:
9 11 17 20 22
10 18 19 23 24
</pre>
 
=== Cursor ===
Line 904 ⟶ 2,531:
Ported from the Java example
 
<langsyntaxhighlight lang="groovy">def zz = { n->
move = { i, j -> j < n - 1 ? [i <= 0 ? 0 : i-1, j+1] : [i+1, j] }
grid = new int[n][n]
Line 914 ⟶ 2,541:
}
grid
}</langsyntaxhighlight>
 
Output
 
{{out}}
<pre>
> zz(5).each { it.each { print("${it}".padLeft(3)) }; println() }
0 1 5 6 14
Line 924 ⟶ 2,551:
9 11 17 20 22
10 18 19 23 24
</pre>
 
=== Sorting ===
 
Ported from the Python example with some input from J
 
<langsyntaxhighlight lang="groovy">def zz = { n ->
(0..<n*n).collect { [x:it%n,y:(int)(it/n)] }.sort { c->
[c.x+c.y, (((c.x+c.y)%2) ? c.y : -c.y)]
}.with { l -> l.inject(new int[n][n]) { a, c -> a[c.y][c.x] = l.indexOf(c); a } }
}</langsyntaxhighlight>
 
Output
 
{{out}}
<pre>
> zz(5).each { it.each { print("${it}".padLeft(3)) }; println() }
0 1 5 6 14
Line 943 ⟶ 2,570:
9 11 17 20 22
10 18 19 23 24
</pre>
 
=={{header|Haskell}}==
Line 948 ⟶ 2,576:
Computing the array:
 
<langsyntaxhighlight lang="haskell">import Data.Array (Array, array, bounds, range, (!))
import DataText.MonoidPrintf (mappendprintf)
import Data.List (sortBy)
 
compZig :: (xInt,y Int) -> (x'Int,y' Int) =-> compare (x+y) (x'+y')Ordering
compZig (x, y) (x_, y_) = compare (x + y) (x_ + y_) <> go x y
`mappend` if even (x+y) then compare x x'
where
else compare y y'
go x y
| even (x + y) = compare x x_
| otherwise = compare y y_
 
zigZag upper:: =(Int, arrayInt) b-> $ zipArray (sortByInt, compZigInt) (range b))Int
zigZag upper = array b $ zip (sortBy compZig (range b)) [0 ..]
where b = ((0,0),upper)</lang>
b = ((0, 0), upper)</syntaxhighlight>
<tt>compZig</tt> compares coordinates using the order of a zigzag walk: primarily, the antidiagonals; secondarily, alternating directions along them.
primarily, the antidiagonals; secondarily, alternating directions along them.
 
In <tt>zigZag</tt>, <tt>array</tt> takes the bounds and a list of indexes paired with values. We take the list of all indexes, <tt>range b</tt>, and sort it in the zigzag order, then zip that with the integers starting from 0. (This algorithm was inspired by the explanation of the J example.)
We take the list of all indexes, <tt>range b</tt>, and sort it in the zigzag order, then zip that with the integers starting from 0.
(This algorithm was inspired by the explanation of the J example.)
 
Displaying the array (not part of the task):
 
<syntaxhighlight lang="haskell">-- format a 2d array of integers neatly
<lang haskell>import Text.Printf (printf)
show2d a =
unlines
[ unwords
[ printf "%3d" (a ! (x, y) :: Integer)
| x <- axis fst ]
| y <- axis snd ]
where
(l, h) = bounds a
axis f = [f l .. f h]
 
main = mapM_ (putStr . ('\n' :) . show2d . zigZag) [(3, 3), (4, 4), (10, 2)]</syntaxhighlight>
-- format a 2d array of integers neatly
show2d a = unlines [unwords [printf "%3d" (a ! (x,y) :: Integer) | x <- axis fst] | y <- axis snd]
where (l, h) = bounds a
axis f = [f l .. f h]
 
 
main = mapM_ (putStr . show2d . zigZag) [(3,3), (4,4), (10,2)]</lang>
Or, building a list of lists with mapAccumL:
<syntaxhighlight lang="haskell">import Data.Text (justifyRight, pack, unpack)
import Data.List (mapAccumL)
import Data.Bool (bool)
 
zigZag :: Int -> [[Int]]
zigZag = go <*> diagonals
where
go _ [] = []
go n xss = (head <$> edge) : go n (dropWhile null (tail <$> edge) <> rst)
where
(edge, rst) = splitAt n xss
 
diagonals :: Int -> [[Int]]
diagonals n =
snd $ mapAccumL go [0 .. (n * n) - 1] (slope <> [n] <> reverse slope)
where
slope = [1 .. n - 1]
go xs h = (rst, bool id reverse (0 /= mod h 2) grp)
where
(grp, rst) = splitAt h xs
 
main :: IO ()
main =
putStrLn $
unlines $
concatMap unpack . fmap (justifyRight 3 ' ' . pack . show) <$> zigZag 5</syntaxhighlight>
{{Out}}
<pre> 0 1 5 6 14
2 4 7 13 15
3 8 12 16 21
9 11 17 20 22
10 18 19 23 24</pre>
 
=={{header|Icon}} and {{header|Unicon}}==
This solution works for both Icon and Unicon.
 
<langsyntaxhighlight lang="icon">procedure main(args)
n := integer(!args) | 5
every !(A := list(n)) := list(n)
Line 1,002 ⟶ 2,676:
then if x[2] = n then [x[1]+1, x[2]] else [max(1, x[1]-1), x[2]+1]
else if x[1] = n then [x[1], x[2]+1] else [x[1]+1, max(1, x[2]-1)]
end</langsyntaxhighlight>
 
{{out}}
Output:
<pre>->zz
0 1 5 6 14
Line 1,013 ⟶ 2,687:
->
</pre>
 
=={{header|IS-BASIC}}==
<syntaxhighlight lang="is-basic">100 PROGRAM "ZigZag.bas"
110 LET SIZE=5
120 NUMERIC A(1 TO SIZE,1 TO SIZE)
130 LET I,J=1
140 FOR E=0 TO SIZE^2-1
150 LET A(I,J)=E
160 IF ((I+J) BAND 1)=0 THEN
170 IF J<SIZE THEN
180 LET J=J+1
190 ELSE
200 LET I=I+2
210 END IF
220 IF I>1 THEN LET I=I-1
230 ELSE
240 IF I<SIZE THEN
250 LET I=I+1
260 ELSE
270 LET J=J+2
280 END IF
290 IF J>1 THEN LET J=J-1
300 END IF
310 NEXT
320 FOR ROW=1 TO SIZE
330 FOR COL=1 TO SIZE
340 PRINT USING " ##":A(ROW,COL);
350 NEXT
360 PRINT
370 NEXT</syntaxhighlight>
 
=={{header|J}}==
 
A succinct way:
<langsyntaxhighlight lang="j"> ($ [: /:@; <@|.`</.@i.)@,~ 5
0 1 5 6 14
2 4 7 13 15
3 8 12 16 21
9 11 17 20 22
10 18 19 23 24</langsyntaxhighlight>
 
This version is longer, but more "mathematical" and less "procedural":
<langsyntaxhighlight lang="j"> ($ [: /:@; [: <@(A.~_2|#)/. i.)@,~ 5
0 1 5 6 14
2 4 7 13 15
3 8 12 16 21
9 11 17 20 22
10 18 19 23 24</langsyntaxhighlight>
 
Leveraging a [[Talk:Zig Zag#reading_the_J_examples|useful relationship among the indices]]:
<langsyntaxhighlight lang="j"> ($ ([: /:@;@(+/"1 <@|.`</. ]) (#: i.@(*/))))@,~ 5
0 1 5 6 14
2 4 7 13 15
3 8 12 16 21
9 11 17 20 22
10 18 19 23 24</langsyntaxhighlight>
 
(Also, of course, <code>($ [: /:@; <@|.`</.@i.)@,~0</code> creates a result with 0 rows and 0 columns. And, with an argument of 1, the result has one row and one column with the value <code>0</code>. And, the other expressions behave the same.)
 
By the way, all the edge cases are handled transparently, without any special checks. Furthermore, by simply ''removing'' the trailing <tt>@,~</tt> from the solutions, they automatically generalize to rectangular (non-square) matrices:
from the solutions, they automatically generalize
<lang j> ($ [: /:@; [: <@|.`</. i.) 5 3
to rectangular (non-square) matrices:
<syntaxhighlight lang="j"> ($ [: /:@; [: <@|.`</. i.) 5 3
0 1 5
2 4 6
3 7 11
8 10 12
9 13 14</langsyntaxhighlight>
 
=={{header|Java}}==
{{trans|Ada}}
<langsyntaxhighlight lang="java">public static int[][] Zig_Zag(final int size)
{
int[][] data = new int[size][size];
Line 1,080 ⟶ 2,788:
}
return data;
}</langsyntaxhighlight>
 
=={{header|JavaScript}}==
 
===Imperative===
 
{{works with|SpiderMonkey}} for the <code>print()</code> function.
 
Line 1,088 ⟶ 2,799:
 
Subclasses the Matrix class defined at [[Matrix Transpose#JavaScript]]
<langsyntaxhighlight lang="javascript">function ZigZagMatrix(n) {
this.height = n;
this.width = n;
Line 1,119 ⟶ 2,830:
 
z = new ZigZagMatrix(4);
print(z);</langsyntaxhighlight>
{{out}}
output
<pre>0,1,5,6,14
2,4,7,13,15
Line 1,131 ⟶ 2,842:
3,8,11,13
9,10,14,15</pre>
 
===Functional===
 
====ES5====
 
<syntaxhighlight lang="javascript">(function (n) {
 
// Read range of values into a series of 'diagonal rows'
// for a square of given dimension,
// starting at diagonal row i.
// [
// [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]
// ]
 
// diagonals :: n -> [[n]]
function diagonals(n) {
function diags(xs, iCol, iRow) {
if (iCol < xs.length) {
var xxs = splitAt(iCol, xs);
 
return [xxs[0]].concat(diags(
xxs[1],
(iCol + (iRow < n ? 1 : -1)),
iRow + 1
));
} else return [xs];
}
 
return diags(range(0, n * n - 1), 1, 1);
}
 
 
 
// Recursively read off n heads from the diagonals (as rows)
// n -> [[n]] -> [[n]]
function nHeads(n, lst) {
var zipEdge = lst.slice(0, n);
 
return lst.length ? [zipEdge.map(function (x) {
return x[0];
})].concat(nHeads(n, [].concat.apply([], zipEdge.map(function (
x) {
return x.length > 1 ? [x.slice(1)] : [];
}))
.concat(lst.slice(n)))) : [];
}
 
// range(intFrom, intTo, optional intStep)
// Int -> Int -> Maybe Int -> [Int]
function range(m, n, delta) {
var d = delta || 1,
blnUp = n > m,
lng = Math.floor((blnUp ? n - m : m - n) / d) + 1,
a = Array(lng),
i = lng;
 
if (blnUp)
while (i--) a[i] = (d * i) + m;
else
while (i--) a[i] = m - (d * i);
return a;
}
 
// splitAt :: Int -> [a] -> ([a],[a])
function splitAt(n, xs) {
return [xs.slice(0, n), xs.slice(n)];
}
 
// Recursively take n heads from the alternately reversed diagonals
 
// [ [
// [0], -> [0, 1, 5, 6, 14] and:
// [1, 2], [2],
// [5, 4, 3], [4, 3],
// [6, 7, 8, 9], [7, 8, 9],
// [14, 13, 12, 11, 10], [13, 12, 11, 10],
// [15, 16, 17, 18], [15, 16, 17, 18],
// [21, 20, 19], [21, 20, 19],
// [22, 23], [22, 23],
// [24] [24]
// ] ]
//
// In the next recursion with the remnant on the right, the next
// 5 heads will be [2, 4, 7, 13, 15] - the second row of our zig zag matrix.
// (and so forth)
 
 
return nHeads(n, diagonals(n)
.map(function (x, i) {
i % 2 || x.reverse();
return x;
}));
 
})(5);</syntaxhighlight>
 
{{Out}}
 
<pre>[[0, 1, 5, 6, 14],
[2, 4, 7, 13, 15],
[3, 8, 12, 16, 21],
[9, 11, 17, 20, 22],
[10, 18, 19, 23, 24]]</pre>
 
====ES6====
 
<syntaxhighlight lang="javascript">(n => {
 
// diagonals :: n -> [[n]]
function diagonals(n) {
let diags = (xs, iCol, iRow) => {
if (iCol < xs.length) {
let xxs = splitAt(iCol, xs);
 
return [xxs[0]].concat(diags(
xxs[1],
iCol + (iRow < n ? 1 : -1),
iRow + 1
));
} else return [xs];
}
 
return diags(range(0, n * n - 1), 1, 1);
}
 
 
// Recursively read off n heads of diagonal lists
// rowsFromDiagonals :: n -> [[n]] -> [[n]]
function rowsFromDiagonals(n, lst) {
if (lst.length) {
let [edge, rest] = splitAt(n, lst);
 
return [edge.map(x => x[0])]
.concat(rowsFromDiagonals(n,
edge.filter(x => x.length > 1)
.map(x => x.slice(1))
.concat(rest)
));
} else return [];
}
 
// GENERIC FUNCTIONS
 
// splitAt :: Int -> [a] -> ([a],[a])
function splitAt(n, xs) {
return [xs.slice(0, n), xs.slice(n)];
}
 
// range :: From -> To -> Maybe Step -> [Int]
// range :: Int -> Int -> Maybe Int -> [Int]
function range(m, n, step) {
let d = (step || 1) * (n >= m ? 1 : -1);
 
return Array.from({
length: Math.floor((n - m) / d) + 1
}, (_, i) => m + (i * d));
}
 
// ZIG-ZAG MATRIX
 
return rowsFromDiagonals(n,
diagonals(n)
.map((x, i) => (i % 2 || x.reverse()) && x)
);
 
})(5);</syntaxhighlight>
 
{{Out}}
<pre>[[0, 1, 5, 6, 14],
[2, 4, 7, 13, 15],
[3, 8, 12, 16, 21],
[9, 11, 17, 20, 22],
[10, 18, 19, 23, 24]]</pre>
 
=={{header|Joy}}==
<syntaxhighlight lang="joy">
<lang Joy>
(*
From the library.
Line 1,184 ⟶ 3,075:
concat [step '\n putch] cons step.
 
11 zigzag.</syntaxhighlight>
 
</lang>
=={{header|jq}}==
Infrastructure:
<syntaxhighlight lang="jq"># Create an m x n matrix
def matrix(m; n; init):
if m == 0 then []
elif m == 1 then [range(0;n)] | map(init)
elif m > 0 then
matrix(1;n;init) as $row
| [range(0;m)] | map( $row )
else error("matrix\(m);_;_) invalid")
end ;
 
# Print a matrix neatly, each cell occupying n spaces
def neatly(n):
def right: tostring | ( " " * (n-length) + .);
. as $in
| length as $length
| reduce range (0;$length) as $i
(""; . + reduce range(0;$length) as $j
(""; "\(.) \($in[$i][$j] | right )" ) + "\n" ) ;
</syntaxhighlight>
Create a zigzag matrix by zigzagging:
<syntaxhighlight lang="jq">def zigzag(n):
 
# unless m == n*n, place m at (i,j), pointing
# in the direction d, where d = [drow, dcolumn]:
def _next(i; j; m; d):
if m == (n*n) then . else .[i][j] = m end
| if m == (n*n) - 1 then .
elif i == n-1 then if j+1 < n then .[i][j+1] = m+1 | _next(i-1; j+2; m+2; [-1, 1]) else . end
elif i == 0 then if j+1 < n then .[i][j+1] = m+1 | _next(i+1; j ; m+2; [ 1,-1])
else .[i+1][j] = m+1 | _next(i+2; j-1; m+2; [ 1,-1]) end
elif j == n-1 then if i+1 < n then .[i+1][j] = m+1 | _next(i+2; j-1; m+2; [ 1,-1]) else . end
elif j == 0 then if i+1 < n then .[i+1][j] = m+1 | _next(i; j+1; m+2; [-1, 1])
else .[i][j+1] = m+1 | _next(i-1; j+1; m+2; [-1, 1]) end
else _next(i+ d[0]; j+ d[1]; m+1; d)
end ;
matrix(n;n;-1) | _next(0;0; 0; [0,1]) ;
 
# Example
zigzag(5) | neatly(4)</syntaxhighlight>
{{out}}
<pre>
$ jq -n -r -f zigzag.jq
0 1 5 6 14
2 4 7 13 15
3 8 12 16 21
9 11 17 20 22
10 18 19 23 24
</pre>
=== another solution ===
<syntaxhighlight lang="jq">#!/usr/bin/env jq -Mnrc -f
#
# solve zigzag matrix by constructing list of 2n+1 column "runs"
# and then shifting them into final form.
#
# e.g. for n=3 initial runs are [[0],[1,2],[3,4,5],[6,7],[8]]
# runs below are shown as columns:
#
# initial column runs 0 1 3 6 8
# 2 4 7
# 5
#
# reverse cols 0,2,4 0 1 5 6 8
# 2 4 7
# 3
#
# shift cols 3,4 down 0 1 5
# 2 4 6
# 3 7 8
#
# shift rows left 0 1 5
# to get final zigzag 2 4 6
# 3 7 8
 
def N: $n ; # size of matrix
def NR: 2*N - 1; # number of runs
def abs: if .<0 then -. else . end ; # absolute value
def runlen: N-(N-.|abs) ; # length of run
def makeruns: [
foreach range(1;NR+1) as $r ( # for each run
{c:0} # state counter
; .l = ($r|runlen) # length of this run
| .r = [range(.c;.c+.l)] # values in this run
| .c += .l # increment counter
; .r # produce run
) ] ; # collect into array
def even: .%2==0 ; # is input even?
def reverseruns: # reverse alternate runs
.[keys|map(select(even))[]] |= reverse ;
def zeros: [range(.|N-length)|0] ; # array of padding zeros
def shiftdown:
def pad($r): # pad run with zeros
if $r < N # determine where zeros go
then . = . + zeros # at back for left runs
else . = zeros + . # at front for right runs
end ;
reduce keys[] as $r (.;.[$r] |= pad($r)); # shift rows down with pad
def shiftleft: [
range(N) as $r
| [ range($r;$r+N) as $c
| .[$c][$r]
]
] ;
def width: [.[][]]|max|tostring|1+length; # width of largest value
def justify($w): (($w-length)*" ") + . ; # leading spaces
def format:
width as $w # compute width
| map(map(tostring | justify($w)))[] # justify values
| join(" ")
;
makeruns # create column runs
| reverseruns # reverse alternate runs
| shiftdown # shift right runs down
| shiftleft # shift rows left
| format # format final result</syntaxhighlight>
{{out}}
<pre>
$ ./zigzag.jq --argjson n 8
0 1 5 6 14 15 27 28
2 4 7 13 16 26 29 42
3 8 12 17 25 30 41 43
9 11 18 24 31 40 44 53
10 19 23 32 39 45 52 54
20 22 33 38 46 51 55 60
21 34 37 47 50 56 59 61
35 36 48 49 57 58 62 63
</pre>
 
=={{header|Julia}}==
=== simple solution ===
<syntaxhighlight lang="julia">function zigzag_matrix(n::Int)
matrix = zeros(Int, n, n)
x, y = 1, 1
for i = 0:(n*n-1)
matrix[y,x] = i
if (x + y) % 2 == 0
# Even stripes
if x < n
x += 1
y -= (y > 1)
else
y += 1
end
else
# Odd stripes
if y < n
x -= (x > 1)
y += 1
else
x += 1
end
end
end
return matrix
end</syntaxhighlight>
 
{{out}}
<pre>julia> zigzag_matrix(5)
5×5 Array{Int64,2}:
0 1 5 6 14
2 4 7 13 15
3 8 12 16 21
9 11 17 20 22
10 18 19 23 24
</pre>
 
=== a more generic solution ===
Create an iterator that steps through a matrix's indices in the zig-zag pattern and use this to create zig-zag matrices and related objects.
 
'''Zig-Zag Iterator'''
<syntaxhighlight lang="julia">
immutable ZigZag
m::Int
n::Int
diag::Array{Int,1}
cmax::Int
numd::Int
lohi::(Int,Int)
end
function zigzag(m::Int, n::Int)
0<m && 0<n || error("The matrix dimensions must be positive.")
ZigZag(m, n, [-1,1], m*n, m+n-1, extrema([m,n]))
end
zigzag(n::Int) = zigzag(n, n)
 
type ZZState
cnt::Int
cell::Array{Int,1}
dir::Int
dnum::Int
dlen::Int
dcnt::Int
end
 
Base.length(zz::ZigZag) = zz.cmax
Base.start(zz::ZigZag) = ZZState(1, [1,1], 1, 1, 1, 1)
Base.done(zz::ZigZag, zzs::ZZState) = zzs.cnt > zz.cmax
 
function Base.next(zz::ZigZag, zzs::ZZState)
s = sub2ind((zz.m, zz.n), zzs.cell[1], zzs.cell[2])
if zzs.dcnt == zzs.dlen
if isodd(zzs.dnum)
if zzs.cell[2] < zz.n
zzs.cell[2] += 1
else
zzs.cell[1] += 1
end
else
if zzs.cell[1] < zz.m
zzs.cell[1] += 1
else
zzs.cell[2] += 1
end
end
zzs.dcnt = 1
zzs.dnum += 1
zzs.dir = -zzs.dir
if zzs.dnum <= zz.lohi[1]
zzs.dlen += 1
elseif zz.lohi[2] < zzs.dnum
zzs.dlen -= 1
end
else
zzs.cell += zzs.dir*zz.diag
zzs.dcnt += 1
end
zzs.cnt += 1
return (s, zzs)
end
</syntaxhighlight>
 
'''Helper Functions'''
<syntaxhighlight lang="julia">
using Formatting
 
function width{T<:Integer}(n::T)
w = ndigits(n)
n < 0 || return w
return w + 1
end
 
function pretty{T<:Integer}(a::Array{T,2}, indent::Int=4)
lo, hi = extrema(a)
w = max(width(lo), width(hi))
id = " "^indent
fe = FormatExpr(@sprintf(" {:%dd}", w))
s = id
nrow = size(a)[1]
for i in 1:nrow
for j in a[i,:]
s *= format(fe, j)
end
i != nrow || continue
s *= "\n"*id
end
return s
end
</syntaxhighlight>
 
'''Main'''
<syntaxhighlight lang="julia">
n = 5
println("The n = ", n, " zig-zag matrix:")
a = zeros(Int, (n, n))
for (i, s) in enumerate(zigzag(n))
a[s] = i-1
end
println(pretty(a))
 
m = 3
println()
println("Generalize to a non-square matrix (", m, "x", n, "):")
a = zeros(Int, (m, n))
for (i, s) in enumerate(zigzag(m, n))
a[s] = i-1
end
println(pretty(a))
 
p = primes(10^3)
n = 7
println()
println("An n = ", n, " prime spiral matrix:")
a = zeros(Int, (n, n))
for (i, s) in enumerate(zigzag(n))
a[s] = p[i]
end
println(pretty(a))
</syntaxhighlight>
 
{{out}}
<pre>
The n = 5 zig-zag matrix:
0 1 5 6 14
2 4 7 13 15
3 8 12 16 21
9 11 17 20 22
10 18 19 23 24
 
Generalize to a non-square matrix (3x5):
0 1 5 6 11
2 4 7 10 12
3 8 9 13 14
 
An n = 7 prime spiral matrix:
2 3 13 17 47 53 107
5 11 19 43 59 103 109
7 23 41 61 101 113 167
29 37 67 97 127 163 173
31 71 89 131 157 179 199
73 83 137 151 181 197 211
79 139 149 191 193 223 227
</pre>
 
=={{header|Klingphix}}==
<syntaxhighlight lang="klingphix">include ..\Utilitys.tlhy
 
 
%Size 5 !Size
0 ( $Size dup ) dim
%i 1 !i %j 1 !j
 
$Size 2 power [
1 -
( $i $j ) set
$i $j + 1 band 0 == (
[$j $Size < ( [$j 1 + !j] [$i 2 + !i] ) if
$i 1 > [ $i 1 - !i] if ]
[$i $Size < ( [$i 1 + !i] [$j 2 + !j] ) if
$j 1 > [ $j 1 - !j] if ]
) if
] for
$Size [
%row !row
$Size [
%col !col
( $row $col ) get tostr 32 32 chain chain 1 3 slice print drop
] for
nl
] for
 
 
nl "End " input</syntaxhighlight>
{{out}}
<pre>0 1 5 6 14
2 4 7 13 15
3 8 12 16 21
9 11 17 20 22
10 18 19 23 24
 
End</pre>
 
=={{header|K}}==
 
'''Works with:''' [[ngnk|ngn/k]]
 
<syntaxhighlight>
f:{grid:+x#<<a,'(!#a)*- 2!a:+/!x,:x
padded:(-#$-1+*/x)$$grid
`0:" "/'padded}
f 5
</syntaxhighlight>
 
{{out}}
<pre>
0 1 5 6 14
2 4 7 13 15
3 8 12 16 21
9 11 17 20 22
10 18 19 23 24
</pre>
 
=={{header|Kotlin}}==
<syntaxhighlight lang="scala">// version 1.1.3
 
typealias Vector = IntArray
typealias Matrix = Array<Vector>
 
fun zigzagMatrix(n: Int): Matrix {
val result = Matrix(n) { Vector(n) }
var down = false
var count = 0
for (col in 0 until n) {
if (down)
for (row in 0..col) result[row][col - row] = count++
else
for (row in col downTo 0) result[row][col - row] = count++
down = !down
}
for (row in 1 until n) {
if (down)
for (col in n - 1 downTo row) result[row + n - 1 - col][col] = count++
else
for (col in row until n) result[row + n - 1 - col][col] = count++
down = !down
}
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(zigzagMatrix(5))
printMatrix(zigzagMatrix(10))
}</syntaxhighlight>
 
{{out}}
<pre>
0 1 5 6 14
2 4 7 13 15
3 8 12 16 21
9 11 17 20 22
10 18 19 23 24
 
0 1 5 6 14 15 27 28 44 45
2 4 7 13 16 26 29 43 46 63
3 8 12 17 25 30 42 47 62 64
9 11 18 24 31 41 48 61 65 78
10 19 23 32 40 49 60 66 77 79
20 22 33 39 50 59 67 76 80 89
21 34 38 51 58 68 75 81 88 90
35 37 52 57 69 74 82 87 91 96
36 53 56 70 73 83 86 92 95 97
54 55 71 72 84 85 93 94 98 99
</pre>
 
=={{header|Ksh}}==
<syntaxhighlight lang="ksh">
#!/bin/ksh
 
# Produce a zig-zag array.
 
# # Variables:
#
integer DEF_SIZE=5 # Default size = 5
arr_size=${1:-$DEF_SIZE} # $1 = size, or default
 
# # Externals:
#
 
# # Functions:
#
 
 
######
# main #
######
integer i j n
typeset -a zzarr
 
for (( i=n=0; i<arr_size*2; i++ )); do
for (( j= (i<arr_size) ? 0 : i-arr_size+1; j<=i && j<arr_size; j++ )); do
(( zzarr[(i&1) ? j*(arr_size-1)+i : (i-j)*arr_size+j] = n++ ))
done
done
 
for ((i=0; i<arr_size*arr_size; i++)); do
printf "%3d " ${zzarr[i]}
(( (i+1)%arr_size == 0 )) && printf "\n"
done</syntaxhighlight>
{{out}}<pre>
0 1 5 6 14
2 4 7 13 15
3 8 12 16 21
9 11 17 20 22
10 18 19 23 24
 
0 1 5 6 14 15 27 28 44
2 4 7 13 16 26 29 43 45
3 8 12 17 25 30 42 46 59
9 11 18 24 31 41 47 58 60
10 19 23 32 40 48 57 61 70
20 22 33 39 49 56 62 69 71
21 34 38 50 55 63 68 72 77
35 37 51 54 64 67 73 76 78
36 52 53 65 66 74 75 79 80</pre>
 
=={{header|Lasso}}==
 
<syntaxhighlight lang="lasso">
var(
'square' = array
,'size' = integer( 5 )// for a 5 X 5 square
,'row' = array
,'x' = integer( 1 )
,'y' = integer( 1 )
,'counter' = integer( 1 )
);
 
// create place-holder matrix
loop( $size );
$row = array;
 
loop( $size );
$row->insert( 0 );
 
/loop;
 
$square->insert( $row );
 
/loop;
 
while( $counter < $size * $size );
// check downward diagonal
if(
$x > 1
&&
$y < $square->size
&&
$square->get( $y + 1 )->get( $x - 1 ) == 0
);
 
$x -= 1;
$y += 1;
 
// check upward diagonal
else(
$x < $square->size
&&
$y > 1
&&
$square->get( $y - 1 )->get( $x + 1 ) == 0
);
 
$x += 1;
$y -= 1;
 
// check right
else(
(
$y == 1
||
$y == $square->size
)
&&
$x < $square->size
&&
$square->get( $y )->get( $x + 1 ) == 0
);
 
$x += 1;
 
// down
else;
$y += 1;
 
/if;
 
$square->get( $y )->get( $x ) = loop_count;
 
$counter += 1;
 
/while;
 
$square;
</syntaxhighlight>
 
=={{header|Lua}}==
<syntaxhighlight lang="lua">
<lang Lua>
local zigzag = {}
 
Line 1,265 ⟶ 3,721:
 
print(zigzag.new(5))
</syntaxhighlight>
</lang>
 
=={{header|M2000 Interpreter}}==
 
<syntaxhighlight lang="m2000 interpreter">
Module Lib1 {
Module Global PrintArray(&Ar()) {
if dimension(Ar())<>2 then Error "This is for 2D arrays"
integer i, j, n=dimension(Ar(),1), n1=dimension(Ar(),2)
for i=1 to n
for j=1 to n1
print Ar(i, j),
next
print
next
}
Function Global MakeArray(n as integer=5) {
dim a(1 to n, 1 to n) as integer=0
integer i=1, j=1, z, t1=1
boolean ch=true
for z=0 to n*n-1
if ch then a(i,j)=z else a(j,i)=z
j++
if j>t1 then t1++: j=1:i=t1: ch~ else i--
if i<1 then i=t1 else.if i>n then i=n: j++
if j>n then j=i+2: i=n:ch~
next
=a() // return array (as a pointer)
}
}
Module Zig_Zag_Matrix (n as integer=5) {
Pen 15 {Report "matrix "+n+"x"+n}
integer old_column=tab
Print $(,4) // set column to 4 chars
if random(1,2)=2 then
dim ret()
ret()=makeArray(n) // this get a copy
else
object a=makeArray(n) // but this get the copy of pointer
link a to ret() // ret() is reference to a, to array
end if
PrintArray &ret()
Print $(,old_column)
}
Inline Code Lib1 // just execute the code from module lib1 like was here
Form 60, 36 \\ console 60x36 characters
Report 2, "Zig-zag matrix" // 2 for center
Pen 14 {Zig_Zag_Matrix 1}
Pen 11 {Zig_Zag_Matrix 2}
Pen 14 {Zig_Zag_Matrix 3}
Pen 11 {Zig_Zag_Matrix 4}
Pen 14 {Zig_Zag_Matrix 5}
Pen 11 {Zig_Zag_Matrix 10}
</syntaxhighlight>
 
=={{header|M4}}==
<langsyntaxhighlight M4lang="m4">divert(-1)
 
define(`set2d',`define(`$1[$2][$3]',`$4')')
Line 1,297 ⟶ 3,806:
 
zigzag(`a',5)
show2d(`a',5,5)</langsyntaxhighlight>
 
{{out}}
Output:
<pre>
0 1 5 6 14
Line 1,308 ⟶ 3,817:
</pre>
 
=={{header|MathematicaMaple}}==
{{trans|Stata}}
Rule-based implementation, the upper-left half is correctly calculated using a direct formula. The lower-right half is then 'mirrored' from the upper-left half.
 
<lang Mathematica>ZigZag[size_Integer/;size>0]:=Module[{empty=ConstantArray[0,{size,size}]},
Here values are starting at 1. Replace <code><v+~1,v+~2></code> with <code><v,v+~1></code> to start at 0.
 
<syntaxhighlight lang="maple">zigzag1:=proc(n)
uses ArrayTools;
local i,u,v,a;
u:=Replicate(<-1,1>,n):
v:=Vector[row](1..n,i->i*(2*i-3)):
v:=Reshape(<v+~1,v+~2>,2*n):
a:=Matrix(n,n):
for i to n do
a[...,i]:=v[i+1..i+n];
v+=u
od:
a
end:
 
zigzag2:=proc(n)
local i,v,a;
a:=zigzag1(n);
v:=Vector(1..n-1,i->i^2);
for i from 2 to n do
a[n+2-i..n,i]-=v[1..i-1]
od;
a
end:</syntaxhighlight>
 
<syntaxhighlight lang="maple">zigzag1(6);</syntaxhighlight>
 
{{out}}
 
<pre>Matrix(6, 6, [[ 1, 2, 6, 7, 15, 16],
[ 3, 5, 8, 14, 17, 27],
[ 4, 9, 13, 18, 26, 31],
[10, 12, 19, 25, 32, 42],
[11, 20, 24, 33, 41, 50],
[21, 23, 34, 40, 51, 61]])</pre>
 
<syntaxhighlight lang="maple">zigzag2(6);</syntaxhighlight>
 
{{out}}
 
<pre>Matrix(6, 6, [[ 1, 2, 6, 7, 15, 16],
[ 3, 5, 8, 14, 17, 26],
[ 4, 9, 13, 18, 25, 27],
[10, 12, 19, 24, 28, 33],
[11, 20, 23, 29, 32, 34],
[21, 22, 30, 31, 35, 36]])</pre>
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
Rule-based implementation, the upper-left half is correctly calculated
using a direct formula.
The lower-right half is then 'mirrored' from the upper-left half.
<syntaxhighlight lang="mathematica">ZigZag[size_Integer/;size>0]:=Module[{empty=ConstantArray[0,{size,size}]},
empty=ReplacePart[empty,{i_,j_}:>1/2 (i+j)^2-(i+j)/2-i (1-Mod[i+j,2])-j Mod[i+j,2]];
ReplacePart[empty,{i_,j_}/;i+j>size+1:> size^2-tmp[[size-i+1,size-j+1]]-1]
]</langsyntaxhighlight>
Ported from the java-example:
<langsyntaxhighlight Mathematicalang="mathematica">ZigZag2[size_] := Module[{data, i, j, elem},
data = ConstantArray[0, {size, size}];
i = j = 1;
Line 1,329 ⟶ 3,891:
];
data
]</langsyntaxhighlight>
Examples:
<langsyntaxhighlight Mathematicalang="mathematica">ZigZag[5] // MatrixForm
ZigZag2[6] // MatrixForm</langsyntaxhighlight>
gives back:
 
Line 1,361 ⟶ 3,923:
 
=={{header|MATLAB}}==
This isn't the best way to solve this task and the algorithm is completely unintuitive without some major exploration of the code. But! It is pretty fast for n < 10000.
and the algorithm is completely unintuitive
without some major exploration of the code.
But! It is pretty fast for n < 10000.
 
<langsyntaxhighlight MATLABlang="matlab">function matrix = zigZag(n)
 
%This is very unintiutive. This algorithm parameterizes the
Line 1,380 ⟶ 3,945:
column = (1:i);
%Causes the zig-zagging. Without these conditionals, you would end
%you would end up with a diagonal matrix. To see what happens comment these conditionals out.
%To see what happens, comment these conditionals out.
if flipCol
column = fliplr(column);
Line 1,392 ⟶ 3,958:
end
%Selects a diagonal of the zig-zag matrix and places the correct
%correct integer value in each index along that diagonal
for j = (1:numel(row))
matrix(row(j),column(j)) = counter;
Line 1,405 ⟶ 3,971:
column = (i:n);
%Causes the zig-zagging. Without these conditionals, you would end
%you would end up with a diagonal matrix. To see what happens comment these conditionals out.
%To see what happens comment these conditionals out.
if flipCol
column = fliplr(column);
Line 1,417 ⟶ 3,984:
end
%Selects a diagonal of the zig-zag matrix and places the correct
%correct integer value in each index along that diagonal
for j = (1:numel(row))
matrix(row(j),column(j)) = counter;
Line 1,426 ⟶ 3,993:
end</langsyntaxhighlight>
 
{{out}}
Sample Output:
<lang MATLABpre>>> zigZag(5)
 
ans =
Line 1,437 ⟶ 4,004:
3 8 12 16 21
9 11 17 20 22
10 18 19 23 24</langpre>
 
=={{header|Maxima}}==
<syntaxhighlight lang="maxima">zigzag(n) := block([a, i, j],
a: zeromatrix(n, n),
i: 1,
j: 1,
for k from 0 thru n*n - 1 do (
a[i, j]: k,
if evenp(i + j) then (
if j < n then j: j + 1 else i: i + 2,
if i > 1 then i: i - 1
) else (
if i < n then i: i + 1 else j: j + 2,
if j > 1 then j: j - 1
)
),
a)$
 
zigzag(5);
/* matrix([ 0, 1, 5, 6, 14],
[ 2, 4, 7, 13, 15],
[ 3, 8, 12, 16, 21],
[ 9, 11, 17, 20, 22],
[10, 18, 19, 23, 24]) */</syntaxhighlight>
 
=={{header|MiniZinc}}==
<syntaxhighlight lang="minizinc">
%Zigzag Matrix. Nigel Galloway, February 3rd., 2020
int: Size;
array [1..Size,1..Size] of var 1..Size*Size: zigzag;
constraint zigzag[1,1]=1 /\ zigzag[Size,Size]=Size*Size;
constraint forall(n in {2*g | g in 1..Size div 2})(zigzag[1,n]=zigzag[1,n-1]+1 /\ forall(g in 2..n)(zigzag[g,n-g+1]=zigzag[g-1,n-g+2]+1));
constraint forall(n in {2*g + ((Size-1) mod 2) | g in 1..(Size-1) div 2})(zigzag[n,Size]=zigzag[n-1,Size]+1 /\ forall(g in 1..Size-n)(zigzag[n+g,Size-g]=zigzag[n+g-1,Size-g+1]+1));
constraint forall(n in {2*g+1 | g in 1..(Size-1) div 2})(zigzag[n,1]=zigzag[n-1,1]+1 /\ forall(g in 2..n)(zigzag[n-g+1,g]=zigzag[n-g+2,g-1]+1));
constraint forall(n in {2*g+((Size) mod 2) | g in 1..(Size-1) div 2})(zigzag[Size,n]=zigzag[Size,n-1]+1 /\ forall(g in 1..Size-n)(zigzag[Size-g,n+g]=zigzag[Size-g+1,n+g-1]+1));
output [show2d(zigzag)];
</syntaxhighlight>
{out}
<pre>
minizinc -DSize=5 zigzag.mzn
[| 1, 2, 6, 7, 15 |
3, 5, 8, 14, 16 |
4, 9, 13, 17, 22 |
10, 12, 18, 21, 23 |
11, 19, 20, 24, 25 |]
----------
 
minizinc -DSize=6 zigzag.mzn
[| 1, 2, 6, 7, 15, 16 |
3, 5, 8, 14, 17, 26 |
4, 9, 13, 18, 25, 27 |
10, 12, 19, 24, 28, 33 |
11, 20, 23, 29, 32, 34 |
21, 22, 30, 31, 35, 36 |]
----------
</pre>
 
=={{header|Modula-3}}==
<langsyntaxhighlight lang="modula3">MODULE ZigZag EXPORTS Main;
 
IMPORT IO, Fmt;
Line 1,488 ⟶ 4,110:
BEGIN
Print(Create(5));
END ZigZag.</langsyntaxhighlight>
{{out}}
Output:
<pre>
0 1 5 6 14
Line 1,500 ⟶ 4,122:
=={{header|NetRexx}}==
{{trans|REXX}}
<langsyntaxhighlight NetRexxlang="netrexx">/* NetRexx */
options replace format comments java crossref savelog symbols binary
 
Line 1,541 ⟶ 4,163:
 
return
</syntaxhighlight>
</lang>
 
=={{header|Nim}}==
{{trans|Python}}
<syntaxhighlight lang="nim">from algorithm import sort
from strutils import align
from sequtils import newSeqWith
type Pos = tuple[x, y: int]
 
proc `<` (a, b: Pos): bool =
a.x + a.y < b.x + b.y or
a.x + a.y == b.x + b.y and (a.x < b.x xor (a.x + a.y) mod 2 == 0)
proc zigzagMatrix(n: int): auto =
var indices = newSeqOfCap[Pos](n*n)
for x in 0 ..< n:
for y in 0 ..< n:
indices.add((x,y))
sort(indices)
result = newSeqWith(n, newSeq[int](n))
for i, p in indices:
result[p.x][p.y] = i
 
proc `$`(m: seq[seq[int]]): string =
let Width = len($m[0][^1]) + 1
for r in m:
for c in r:
result.add align($c, Width)
result.add "\n"
echo zigzagMatrix(6)</syntaxhighlight>
{{out}}
<pre> 0 1 5 6 14 15
2 4 7 13 16 25
3 8 12 17 24 26
9 11 18 23 27 32
10 19 22 28 31 33
20 21 29 30 34 35</pre>
 
===Direct coord to number===
This calculates the number for each coordinate directly. This allows to create very large zig-zag matrices. Generates the same output as above.
<syntaxhighlight lang="nim">import strutils
 
func sumTo(n: Natural): Natural = n * (n+1) div 2
 
func coord2num(row, col, N: Natural): Natural =
var start, offset: Natural
let diag = col + row
if diag < N:
start = sumTo(diag)
offset = if diag mod 2 == 0: col else: row
else:
# N * (2*diag+1-N) - sumTo(diag), but with smaller itermediates
start = N*N - sumTo(2*N-1-diag)
offset = N-1 - (if diag mod 2 == 0: row else: col)
start + offset
 
let N = 6
let width = (N*N).`$`.len + 1
for row in 0 ..< N:
for col in 0 ..< N:
stdout.write(coord2num(row, col, N).`$`.align(width))
stdout.write("\n")
</syntaxhighlight>
 
=={{header|Objeck}}==
{{trans|Java}}
<langsyntaxhighlight lang="ocaml">
function : native : ZigZag(size : Int) ~ Int[,] {
data := Int->New[size, size];
Line 1,585 ⟶ 4,274:
return data;
}
</syntaxhighlight>
</lang>
 
 
=={{header|OCaml}}==
Line 1,592 ⟶ 4,280:
{{trans|Common Lisp}}
 
<langsyntaxhighlight lang="ocaml">let zigzag n =
(* move takes references and modifies them directly *)
let move i j =
Line 1,610 ⟶ 4,298:
move y x
done;
a</langsyntaxhighlight>
 
=={{header|Octave}}==
{{trans|Stata}}
See the [[Zig-zag matrix#MATLAB|MATLAB solution]], which works perfectly in Octave too.
 
<syntaxhighlight lang="octave">function a = zigzag1(n)
j = 1:n;
u = repmat([-1; 1], n, 1);
v = j.*(2*j-3);
v = reshape([v; v+1], 2*n, 1);
a = zeros(n, n);
for i = 1:n
a(:, i) = v(i+j);
v += u;
endfor
endfunction
 
function a = zigzag2(n)
a = zigzag1(n);
v = (1:n-1)'.^2;
for i = 2:n
a(n+2-i:n, i) -= v(1:i-1);
endfor
endfunction
 
>> zigzag2(5)
ans =
 
0 1 5 6 14
2 4 7 13 15
3 8 12 16 21
9 11 17 20 22
10 18 19 23 24</syntaxhighlight>
 
Alternate solution, filling pairs of diagonals.
 
<syntaxhighlight lang="octave">function a = zigzag3(n)
a = zeros(n, n);
for k=1:n
d = (2*(j = mod(k, 2))-1)*(n-1);
m = (n-1)*(k-1);
a(k+(1-j)*m:d:k+j*m) = k*(k-1)/2:k*(k+1)/2-1;
a(n*(n+1-k)+(1-j)*m:d:n*(n+1-k)+j*m) = n*n-k*(k+1)/2:n*n-k*(k-1)/2-1;
endfor
endfunction
 
>> zigzag3(5)
ans =
 
0 1 5 6 14
2 4 7 13 15
3 8 12 16 21
9 11 17 20 22
10 18 19 23 24</syntaxhighlight>
 
==Inspired by Rascal==
<syntaxhighlight lang="octave">
#{
Produce a zigzag matrix. Nigel Galloway, January 26th., 2020.
At the time of writing the Rascal solution is yellow flagged for producing a striped matrix.
Let me make the same faux pas.
#}
n=5; g=1;
for e=1:n i=1; for l=e:-1:1 zig(i++,l)=g++; endfor endfor
for e=2:n i=e; for l=n:-1:e zig(i++,l)=g++; endfor endfor
#{
I then have the following, let me call it zig.
1 2 4 7 11
3 5 8 12 16
6 9 13 17 20
10 14 18 21 23
15 19 22 24 25
To avoid being yellow flagged I must convert this striped matrix into a zigzag matrix.
#}
zag=zig'
#{
So zag is the transpose of zig.
1 3 6 10 15
2 5 9 14 19
4 8 13 18 22
7 12 17 21 24
11 16 20 23 25
#}
for e=1:n for g=1:n if(mod(e+g,2))==0 zagM(e,g)=1; endif endfor endfor; zigM=1-zagM;
#{
I now have 2 masks:
zigM =
 
0 1 0 1 0
1 0 1 0 1
0 1 0 1 0
1 0 1 0 1
0 1 0 1 0
 
zagM =
 
1 0 1 0 1
0 1 0 1 0
1 0 1 0 1
0 1 0 1 0
1 0 1 0 1
#}
zigzag=zag.*zagM+zig.*zigM;
#{
zigzag =
 
1 2 6 7 15
3 5 8 14 16
4 9 13 17 22
10 12 18 21 23
11 19 20 24 25
#}
</syntaxhighlight>
 
=={{header|ooRexx}}==
{{trans|Java}}
<syntaxhighlight lang="oorexx">
call printArray zigzag(3)
say
call printArray zigzag(4)
say
call printArray zigzag(5)
 
::routine zigzag
use strict arg size
 
data = .array~new(size, size)
row = 1
col = 1
 
loop element = 0 to (size * size) - 1
data[row, col] = element
-- even stripes
if (row + col) // 2 = 0 then do
if col < size then col += 1
else row += 2
if row > 1 then row -= 1
end
-- odd rows
else do
if row < size then row += 1
else col += 2
if col > 1 then col -= 1
end
end
 
return data
 
::routine printArray
use arg array
dimension = array~dimension(1)
loop i = 1 to dimension
line = "|"
loop j = 1 to dimension
line = line array[i, j]~right(2)
end
line = line "|"
say line
end
</syntaxhighlight>
{{out}}
<pre>
| 0 1 5 |
| 2 4 6 |
| 3 7 8 |
 
| 0 1 5 6 |
| 2 4 7 12 |
| 3 8 11 13 |
| 9 10 14 15 |
 
| 0 1 5 6 14 |
| 2 4 7 13 15 |
| 3 8 12 16 21 |
| 9 11 17 20 22 |
| 10 18 19 23 24 |
</pre>
 
=={{header|Oz}}==
Implemented as a state machine:
<langsyntaxhighlight lang="oz">declare
%% state move success failure
States = unit(right: [ 1# 0 downLeft downInstead]
Line 1,655 ⟶ 4,518:
end
in
{Inspect {CreateZigZag 5}}</langsyntaxhighlight>
 
=={{header|PARI/GP}}==
{{trans|C.23}}
<langsyntaxhighlight lang="parigp">zz(n)={
my(M=matrix(n,n),i,j,d=-1,start,end=n^2-1);
while(ct--,
Line 1,679 ⟶ 4,542:
if(start>end,return(M))
)
};</langsyntaxhighlight>
 
=={{header|Pascal}}==
<langsyntaxhighlight Pascallang="pascal">Program zigzag( input, output );
 
const
size = 5;
Line 1,690 ⟶ 4,553:
element, i, j: integer;
direction: integer;
width, n: integer;
begin
Line 1,695 ⟶ 4,559:
j := 1;
direction := 1;
for element := 10 to (size*size) - 1 do
begin
zzarray[i,j] := element;
Line 1,701 ⟶ 4,565:
j := j - direction;
if (i = 0) then
begin
direction := -direction;
i := i + 1;
if (j > size) then
end;
if (i = size +1) thenbegin
j := size;
begin
direction i := -direction2;
i := i - 1end;
j := j + 2;end
else if (i > size) then
end;
if (j = 0) thenbegin
direction := -direction;
begin
direction i := -directionsize;
j := j + 12;
end;
else if (j = size + 10) then
begin
direction := -direction;
j := j - 1;
i := if (i +> size) 2;then
end; begin
j := 2;
i := size;
end;
end
else if (j > size) then
begin
direction := -direction;
j := size;
i := i + 2;
end;
end;
 
width := 2;
n := size;
while (n > 0) do
begin
width := width + 1;
n := n div 10;
end;
for j := 1 to size do
begin
for i := 1 to size do
write(zzarray[i,j]:3width);
writeln;
end;
end.</langsyntaxhighlight>
 
output
{{out}}
<pre>
10 21 65 76 1514
32 54 87 1413 1615
43 98 1312 1716 2221
9 11 17 20 22
10 12 18 21 23
1110 18 19 2023 24 25
</pre>
 
{{out}} with size set to 6
<pre>
0 1 5 6 14 15
2 4 7 13 16 25
3 8 12 17 24 26
9 11 18 23 27 32
10 19 22 28 31 33
20 21 29 30 34 35
</pre>
 
<br><br>
 
{{trans|Seed7}} <br>
 
<syntaxhighlight lang="pascal">
Program zigzag;
{$APPTYPE CONSOLE}
const
size = 5;
 
var
s: array [1..size, 1..size] of integer;
i, j, d, max, n: integer;
 
begin
i := 1;
j := 1;
d := -1;
max := 0;
n := 0;
max := size * size;
for n := 1 to (max div 2)+1 do begin
s[i,j] := n;
s[size - i + 1,size - j + 1] := max - n + 1;
i:=i+d;
j:=j-d;
if i < 1 then begin
inc(i);
d := -d;
end else if j < 1 then begin
inc(j);
d := -d;
end;
end;
 
for j := 1 to size do
begin
for i := 1 to size do
write(s[i,j]:4);
writeln;
end;
 
end.
</syntaxhighlight>
 
{{out}} Size 5
<pre>
1 3 4 10 11
2 5 9 12 19
6 8 13 18 20
7 14 17 21 24
15 16 22 23 25
</pre>
 
{{out}} Size 8
<pre>
1 3 4 10 11 21 22 36
2 5 9 12 20 23 35 37
6 8 13 19 24 34 38 49
7 14 18 25 33 39 48 50
15 17 26 32 40 47 51 58
16 27 31 41 46 52 57 59
28 30 42 45 53 56 60 63
29 43 44 54 55 61 62 64
</pre>
 
=={{header|Perl}}==
<syntaxhighlight lang="perl">use 5.010;
 
sub zig_zag {
my $n = shift;
my $max_number = $n**2;
my @matrix;
my $number = 0;
for my $j ( 0 .. --$n ) {
for my $i (
$j % 2
? 0 .. $j
: reverse 0 .. $j
)
{
$matrix[$i][ $j - $i ] = $number++;
#next if $j == $n;
$matrix[ $n - $i ][ $n - ( $j - $i ) ] = $max_number - $number;
}
}
return @matrix;
}
 
my @zig_zag_matrix = zig_zag(5);
say join "\t", @{$_} foreach @zig_zag_matrix;
</syntaxhighlight>
 
 
{{trans|Haskell}}
<langsyntaxhighlight lang="perl">sub zig_zag {
my ($w, $h, @r, $n) = @_;
 
Line 1,757 ⟶ 4,744:
}
 
print map{ "@$_\n" } zig_zag(3, 5);</langsyntaxhighlight>
 
=={{header|Perl 6Phix}}==
{{Trans|C#}}
Assuming the same Turtle class that is used in [[Spiral_matrix]]:
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang perl6>sub MAIN($size as Int) {
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
my $t = Turtle.new(dir => northeast);
<span style="color: #004080;">integer</span> <span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">9</span>
my $counter = 0;
<span style="color: #004080;">integer</span> <span style="color: #000000;">zstart</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">zend</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: #000000;">1</span>
for 1 ..^ $size -> $run {
<span style="color: #000080;font-style:italic;">--integer zstart = 1, zend = n*n</span>
for ^$run {
<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;">zend</span><span style="color: #0000FF;">)))</span>
$t.lay-egg($counter++);
<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>
$t.forward;
<span style="color: #004080;">integer</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;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">d</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span>
}
<span style="color: #008080;">while</span> <span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
my $yaw = $run %% 2 ?? -1 !! 1;
<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;">zstart</span><span style="color: #0000FF;">)</span>
$t.turn-right($yaw * 135); $t.forward; $t.turn-right($yaw * 45);
<span style="color: #008080;">if</span> <span style="color: #000000;">zstart</span><span style="color: #0000FF;">=</span><span style="color: #000000;">zend</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
}
<span style="color: #000000;">zstart</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
for $size ... 1 -> $run {
<span style="color: #000000;">m</span><span style="color: #0000FF;">[</span><span style="color: #000000;">n</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;">n</span><span style="color: #0000FF;">-</span><span style="color: #000000;">y</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</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;">zend</span><span style="color: #0000FF;">)</span>
for ^$run -> $ {
<span style="color: #000000;">zend</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">1</span>
$t.lay-egg($counter++);
<span style="color: #000000;">x</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">d</span>
$t.forward;
<span style="color: #000000;">y</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">d</span>
}
<span style="color: #008080;">if</span> <span style="color: #000000;">x</span><span style="color: #0000FF;"><</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span>
$t.turn-left(180); $t.forward;
<span style="color: #000000;">x</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
my $yaw = $run %% 2 ?? 1 !! -1;
<span style="color: #000000;">d</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">d</span>
$t.turn-right($yaw * 45); $t.forward; $t.turn-left($yaw * 45);
<span style="color: #008080;">elsif</span> <span style="color: #000000;">y</span><span style="color: #0000FF;"><</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span>
}
<span style="color: #000000;">y</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
$t.showmap;
<span style="color: #000000;">d</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">d</span>
}</lang>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</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;">n</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">m</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #000000;">m</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #000000;">m</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">))</span>
<!--</syntaxhighlight>-->
Alternative:
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #004080;">integer</span> <span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">5</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: #000000;">1</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: #004080;">integer</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;">1</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">d</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</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: #000000;">1</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">m</span><span style="color: #0000FF;">[</span><span style="color: #000000;">y</span><span style="color: #0000FF;">][</span><span style="color: #000000;">x</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;">d</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">mod</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: #000000;">2</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</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: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">y</span><span style="color: #0000FF;"><</span><span style="color: #000000;">n</span><span style="color: #0000FF;">?{</span><span style="color: #000000;">x</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;">1</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: #008080;">else</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: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;"><</span><span style="color: #000000;">n</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;">y</span><span style="color: #0000FF;">></span><span style="color: #000000;">1</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: #000000;">1</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</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;">n</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">m</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #000000;">m</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #000000;">m</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">))</span>
<!--</syntaxhighlight>-->
 
=={{header|Phixmonti}}==
<syntaxhighlight lang="phixmonti">5 var Size
0 Size repeat Size repeat
 
1 var i 1 var j
 
Size 2 power for
swap i get rot j set i set
i j + 1 bitand 0 == IF
j Size < IF j 1 + var j ELSE i 2 + var i ENDIF
i 1 > IF i 1 - var i ENDIF
ELSE
i Size < IF i 1 + var i ELSE j 2 + var j ENDIF
j 1 > IF j 1 - var j ENDIF
ENDIF
endfor
 
Size FOR
var row
Size FOR
var col
row get col get tostr 32 32 chain chain 1 3 slice print drop drop
ENDFOR
nl
ENDFOR</syntaxhighlight>
 
=={{header|PHP}}==
<langsyntaxhighlight lang="php">function ZigZagMatrix($num) {
$matrix = array();
for ($i = 0; $i < $num; $i++){
Line 1,816 ⟶ 4,857:
}
return $matrix;
}</langsyntaxhighlight>
 
=={{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.
<syntaxhighlight lang="picolisp">(load "@lib/simul.l")
 
(de zigzag (N)
(prog1 (grid N N)
(let (D '(north west south east .) E '(north east .) This 'a1)
(for Val (* N N)
(=: val Val)
(setq This
(or
((cadr D) ((car D) This))
(prog
(setq D (cddr D))
((pop 'E) This) )
((pop 'E) This) ) ) ) ) ) )
 
(mapc
'((L)
(for This L (prin (align 3 (: val))))
(prinl) )
(zigzag 5) )</syntaxhighlight>
{{out}}
<pre> 1 2 6 7 15
3 5 8 14 16
4 9 13 17 22
10 12 18 21 23
11 19 20 24 25</pre>
 
=={{header|PL/I}}==
<syntaxhighlight lang="pli">/* Fill a square matrix with the values 0 to N**2-1, */
<lang PL/I>
/* Fill a square matrix with the values 0 to N**2-1, */
/* in a zig-zag fashion. */
/* N is the length of one side of the square. */
Line 1,869 ⟶ 4,941:
put skip edit (a(i,*)) (f(4));
end;
end;</syntaxhighlight>
end;
{{out}}
</lang>
<pre> 0 1 5 6 14
2 4 7 13 15
3 8 12 16 21
9 11 17 20 22
10 18 19 23 24 </pre>
 
=={{header|PicoLispPlainTeX}}==
The code works with any etex engine.
This example uses 'grid' from "lib/simul.l", which maintains a two-dimensional
<syntaxhighlight lang="tex">\long\def\antefi#1#2\fi{#2\fi#1}
structure and is normally used for simulations and board games.
\def\fornum#1=#2to#3(#4){%
<lang PicoLisp>(load "@lib/simul.l")
\edef#1{\number\numexpr#2}\edef\fornumtemp{\noexpand\fornumi\expandafter\noexpand\csname fornum\string#1\endcsname
{\number\numexpr#3}{\ifnum\numexpr#4<0 <\else>\fi}{\number\numexpr#4}\noexpand#1}\fornumtemp
}
\long\def\fornumi#1#2#3#4#5#6{\def#1{\unless\ifnum#5#3#2\relax\antefi{#6\edef#5{\number\numexpr#5+(#4)\relax}#1}\fi}#1}
\def\elem(#1,#2){\numexpr(#1+#2)*(#1+#2-1)/2-(\ifodd\numexpr#1+#2\relax#1\else#2\fi)\relax}
\def\zzmat#1{%
\noindent% quit vertical mode
\fornum\yy=1to#1(+1){%
\fornum\xx=1to#1(+1){%
\ifnum\numexpr\xx+\yy\relax<\numexpr#1+2\relax
\hbox to 2em{\hfil\number\elem(\xx,\yy)}%
\else
\hbox to 2em{\hfil\number\numexpr#1*#1-1-\elem(#1+1-\xx,#1+1-\yy)\relax}%
\fi
}%
\par\noindent% next line + quit vertical mode
}\par
}
\zzmat{5}
\bye</syntaxhighlight>
 
pdf output:
(de zigzag (N)
<pre> 0 1 5 6 14
(prog1 (grid N N)
2 4 7 13 15
(let (D '(north west south east .) E '(north east .) This 'a1)
3 8 12 16 (for Val (* N N)21
9 11 17 20 (=: val Val)22
10 18 19 23 (setq This24</pre>
(or
((cadr D) ((car D) This))
(prog
(setq D (cddr D))
((pop 'E) This) )
((pop 'E) This) ) ) ) ) ) )
 
(mapc
'((L)
(for This L (prin (align 3 (: val))))
(prinl) )
(zigzag 5) )</lang>
Output:
<pre> 1 2 6 7 15
3 5 8 14 16
4 9 13 17 22
10 12 18 21 23
11 19 20 24 25</pre>
 
=={{header|PostScript}}==
 
This implementation is far from being elegant or smart, but it builds the ''zigzag'' how a
but it builds the ''zigzag'' how a human being could do,
human being could do, and also draws lines to show the path.
and also draws lines to show the path.
 
<langsyntaxhighlight lang="postscript">%!PS
%%BoundingBox: 0 0 300 200
/size 9 def % defines row * column (9*9 -> 81 numbers,
Line 1,961 ⟶ 5,041:
stroke showpage
} if
%%EOF</langsyntaxhighlight>
 
=={{header|PowerShell}}==
<langsyntaxhighlight PowerShelllang="powershell">function zigzag( [int] $n ) {
$zigzag=New-Object 'Object[,]' $n,$n
$nodd = $n -band 1
Line 2,002 ⟶ 5,082:
} )"
}
}</langsyntaxhighlight>
 
===An Alternate Display===
Display the zig-zag matrix using the <code>Format-Wide</code> cmdlet:
<syntaxhighlight lang="powershell">
zigzag 5 | Format-Wide {"{0,2}" -f $_} -Column 5 -Force
</syntaxhighlight>
{{Out}}
<pre>
0 1 5 6 14
2 4 7 13 15
3 8 12 16 21
9 11 17 20 22
10 18 19 23 24
</pre>
 
=={{header|Prolog}}==
{{Works with SWi|SWI-Prolog.}}
<langsyntaxhighlight Prologlang="prolog">zig_zag(N) :-
zig_zag(N, N).
 
Line 2,074 ⟶ 5,169:
Col is NC - 1,
Lig1 is Lig + 1.
 
 
 
 
Line 2,084 ⟶ 5,177:
print_val(V) :-
writef('%3r ', [V]).
</syntaxhighlight>
</lang>
{{out}}
Output :
<pre>?- zig_zag(5).
0 1 5 6 14
Line 2,115 ⟶ 5,208:
=={{header|PureBasic}}==
{{trans|AutoHotkey}} <br>
<langsyntaxhighlight lang="purebasic">Procedure zigZag(size)
Protected i, v, x, y
Line 2,147 ⟶ 5,240:
Next
 
;generate and show printout
PrintN("Zig-zag matrix of size " + Str(size) + #CRLF$)
Line 2,167 ⟶ 5,260:
Input()
CloseConsole()
EndIf</langsyntaxhighlight>
{{out}}
Sample output:
<pre>Zig-zag matrix of size 5
 
Line 2,188 ⟶ 5,281:
 
=={{header|Python}}==
===Python: By sorting indices===
There is a full explanation of the algorithm used [http://paddy3118.blogspot.com/2008/08/zig-zag.html here].
There is a full explanation of the algorithm used
<lang python>import math
by [http://paddy3118.blogspot.com/2008/08/zig-zag.html paddy3118].
def zigzag(n):
{{Works with|Python|3}}
indexorder = sorted(((x,y) for x in range(n) for y in range(n)),
<syntaxhighlight lang="python">def zigzag(n):
key = lambda (x,y): (x+y, -y if (x+y) % 2 else y) )
'''zigzag rows'''
return dict((index,n) for n,index in enumerate(indexorder))
def compare(xy):
# or, in Python 3: return {index: n for n,index in enumerate(indexorder)}
x, y = xy
return (x + y, -y if (x + y) % 2 else y)
xs = range(n)
return {index: n for n, index in enumerate(sorted(
((x, y) for x in xs for y in xs),
key=compare
))}
 
 
def printzz(myarray):
'''show zigzag rows as lines'''
n = math.round(math.sqrt(len(myarray)))
n = int(len(myarray) ** 0.5 + 0.5)
for x in range(n):
xs for y in= range(n):
print "%2i" % myarray[(x,y)],'\n'.join(
[''.join("%3i" % myarray[(x, y)] for x in xs) for y in xs]
print
))
 
printzz(zigzag(6))</lang>
Program output:
<pre> 0 1 5 6 14 15
2 4 7 13 16 25
3 8 12 17 24 26
9 11 18 23 27 32
10 19 22 28 31 33
20 21 29 30 34 35</pre>
 
printzz(zigzag(6))</syntaxhighlight>
Alternative version, {{trans|Common Lisp}}.
{{out}}
<lang python>def zigzag(n):
<pre> 0 2 3 9 10 20
def move(i, j):
1 4 8 11 if19 j < (n - 1):21
5 7 12 18 22 29
return max(0, i-1), j+1
6 13 17 23 28 else:30
14 16 24 27 31 34
return i+1, j
15 25 26 32 33 35</pre>
a = [[0] * n for _ in xrange(n)]
 
===Alternative version, {{trans|Common Lisp}}===
<syntaxhighlight lang="python">
# pylint: disable=invalid-name
# pylint: disable=unused-argument
"ZigZag iterator."
import sys
 
if sys.version_info[0] >= 3:
xrange = range
 
def move(x, y, columns, rows):
"Tells us what to do next with x and y."
if y < (rows - 1):
return max(0, x-1), y+1
return x+1, y
 
def zigzag(rows, columns):
"ZigZag iterator, yields indices."
x, y = 0, 0
forsize v= in xrange(nrows * n):columns
for _ in a[y][x] = vxrange(size):
yield y, x
if (x + y) & 1:
x, y = move(x, y, columns, rows)
else:
y, x = move(y, x, rows, columns)
 
return a
# test code
i, rows, cols = 0, 5, 5
mat = [[0 for x in range(cols)] for y in range(rows)]
for (y, x) in zigzag(rows, cols):
mat[y][x], i = i, i + 1
 
from pprint import pprint
pprint(zigzag(5mat))</lang>
</syntaxhighlight>
Output:
{{out}}
<lang python>[[0, 1, 5, 6, 14],
 
<syntaxhighlight lang="python">[[0, 1, 5, 6, 14],
[2, 4, 7, 13, 15],
[3, 8, 12, 16, 21],
[9, 11, 17, 20, 22],
[10, 18, 19, 23, 24]]</langsyntaxhighlight>
 
===Alternative version, inspired by the Common Lisp Alternative Approach===
<syntaxhighlight lang="python">
COLS = 9
def CX(x, ran):
while True:
x += 2 * next(ran)
yield x
x += 1
yield x
ran = []
d = -1
for V in CX(1,iter(list(range(0,COLS,2)) + list(range(COLS-1-COLS%2,0,-2)))):
ran.append(iter(range(V, V+COLS*d, d)))
d *= -1
for x in range(0,COLS):
for y in range(x, x+COLS):
print(repr(next(ran[y])).rjust(3), end = ' ')
print()
</syntaxhighlight>
{{out}} COLS = 5 Produces:
<pre>
1 2 6 7 15
3 5 8 14 16
4 9 13 17 22
10 12 18 21 23
11 19 20 24 25
</pre>
{{out}} COLS = 8 Produces:
<pre>
1 2 6 7 15 16 28 29
3 5 8 14 17 27 30 43
4 9 13 18 26 31 42 44
10 12 19 25 32 41 45 54
11 20 24 33 40 46 53 55
21 23 34 39 47 52 56 61
22 35 38 48 51 57 60 62
36 37 49 50 58 59 63 64
</pre>
{{out}} COLS = 9 Produces:
<pre>
1 2 6 7 15 16 28 29 45
3 5 8 14 17 27 30 44 46
4 9 13 18 26 31 43 47 60
10 12 19 25 32 42 48 59 61
11 20 24 33 41 49 58 62 71
21 23 34 40 50 57 63 70 72
22 35 39 51 56 64 69 73 78
36 38 52 55 65 68 74 77 79
37 53 54 66 67 75 76 80 81
</pre>
=== Another alternative version ===
<syntaxhighlight lang="python">
from __future__ import print_function
 
import math
 
 
def zigzag( dimension):
''' generate the zigzag indexes for a square array
Exploiting the fact that an array is symmetrical around its
centre
'''
NUMBER_INDEXES = dimension ** 2
HALFWAY = NUMBER_INDEXES // 2
KERNEL_ODD = dimension & 1
 
xy = [0 for _ in range(NUMBER_INDEXES)]
# start at 0,0
ix = 0
iy = 0
# 'fake' that we are going up and right
direction = 1
# the first index is always 0, so start with the second
# until halfway
for i in range(1, HALFWAY + KERNEL_ODD):
if direction > 0:
# going up and right
if iy == 0:
# are at top
ix += 1
direction = -1
else:
ix += 1
iy -= 1
else:
# going down and left
if ix == 0:
# are at left
iy += 1
direction = 1
else:
ix -= 1
iy += 1
# update the index position
xy[iy * dimension + ix] = i
 
# have first half, but they are scattered over the list
# so find the zeros to replace
for i in range(1, NUMBER_INDEXES):
if xy[i] == 0 :
xy[i] = NUMBER_INDEXES - 1 - xy[NUMBER_INDEXES - 1 - i]
 
return xy
 
 
def main(dim):
zz = zigzag(dim)
print( 'zigzag of {}:'.format(dim))
width = int(math.ceil(math.log10(dim**2)))
for j in range(dim):
for i in range(dim):
print('{:{width}}'.format(zz[j * dim + i], width=width), end=' ')
print()
 
 
if __name__ == '__main__':
main(5)
</syntaxhighlight>
<pre>
zigzag of 5:
0 1 5 6 14
2 4 7 13 15
3 8 12 16 21
9 11 17 20 22
10 18 19 23 24
</pre>
 
=={{header|Quackery}}==
 
===Sorting Indices===
 
{{trans|Python:_By_sorting_indices}}
 
 
<syntaxhighlight lang="quackery"> [ ]'[ tuck do dip do ] is with2 ( x x --> x x )
 
[ dup temp put
[] swap
dup * times [ i^ join ]
sortwith
[ with2
[ temp share /mod
tuck + 1 &
if negate ]
> ]
sortwith
[ with2
[ temp share /mod + ]
> ]
dup witheach
[ i^ unrot poke ]
[] swap
temp share times
[ temp share split
dip [ nested join ] ]
drop
temp release ] is zigzag ( n --> [ )
 
10 zigzag
witheach
[ witheach
[ dup 10 < if sp
echo sp ]
cr ]</syntaxhighlight>
 
{{out}}
 
<pre> 0 1 5 6 14 15 27 28 44 45
2 4 7 13 16 26 29 43 46 63
3 8 12 17 25 30 42 47 62 64
9 11 18 24 31 41 48 61 65 78
10 19 23 32 40 49 60 66 77 79
20 22 33 39 50 59 67 76 80 89
21 34 38 51 58 68 75 81 88 90
35 37 52 57 69 74 82 87 91 96
36 53 56 70 73 83 86 92 95 97
54 55 71 72 84 85 93 94 98 99
</pre>
 
===Turtle style===
 
Adapted from [[Spiral matrix#Quackery]]
 
The sequence of turns for the first half of the matrix is east to southwest to south to northeast to east. In the second half the order of turns is reversed.
 
<syntaxhighlight lang="quackery"> [ stack ] is stepcount ( --> s )
[ stack ] is position ( --> s )
[ stack ] is heading ( --> s )
 
[ heading take
behead join
heading put ] is turn ( --> )
 
[ 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 1 - join
over join
over 1 - negate join
heading put
0 over dup * of
over 1 - times ( turtle draws first half of zigzag )
[ 1 walk turn
i^ 1+ walk turn ]
heading take ( reverse the sequence of turns )
reverse heading put
over 1 - times ( turtle draws second half of zigzag )
[ turn 1 walk
turn i walk ]
1 walk
matrixify ( ...tidy up )
heading release
position release
stepcount release ] is zigzag ( n --> [ )
 
10 zigzag
witheach
[ witheach
[ dup 10 < if sp echo sp ]
cr ]</syntaxhighlight>
 
{{out}}
 
<pre> 0 1 5 6 14 15 27 28 44 45
2 4 7 13 16 26 29 43 46 63
3 8 12 17 25 30 42 47 62 64
9 11 18 24 31 41 48 61 65 78
10 19 23 32 40 49 60 66 77 79
20 22 33 39 50 59 67 76 80 89
21 34 38 51 58 68 75 81 88 90
35 37 52 57 69 74 82 87 91 96
36 53 56 70 73 83 86 92 95 97
54 55 71 72 84 85 93 94 98 99
</pre>
 
=={{header|Qi}}==
Line 2,242 ⟶ 5,619:
The code can probably be simplified somewhat.
 
<syntaxhighlight lang="qi">
<lang qi>
(define odd? A -> (= 1 (MOD A 2)))
(define even? A -> (= 0 (MOD A 2)))
Line 2,268 ⟶ 5,645:
(range 0 N)))
(range 0 N)))
</syntaxhighlight>
</lang>
 
=={{header|R}}==
{{trans|JavaOctave}}
<langsyntaxhighlight Rlang="rsplus">zigzagzigzag1 <- function(sizen) {
j <- seq(n)
{
digitsu <- seq_lenrep(c(size^2) -1, 1), n)
matv <- matrixj * (0,2 nrow* =j size,- ncol=size1) - 1
iv <- as.vector(rbind(v, v + 1))
ja <- 1matrix(0, n, n)
for (elementi in digitsseq(n)) {
a[i, ] <- v[j + i - 1]
{
mat[i,j]v <- elementv + u
}
if((i + j) %% 2 == 0)
{a
# Even stripes
if(j < size) j <- j + 1 else i <- i + 2
if(i > 1) i <- i - 1
} else
{
# Odd stripes
if(i < size) i <- i + 1 else j <- j + 2
if(j > 1) j <- j - 1
}
}
mat
}
 
zigzagzigzag1(5)</langsyntaxhighlight>
 
{{out}}
 
<pre> [,1] [,2] [,3] [,4] [,5]
[1,] 0 1 5 6 14
[2,] 2 4 7 13 16
[3,] 3 8 12 17 25
[4,] 9 11 18 24 31
[5,] 10 19 23 32 40</pre>
 
<syntaxhighlight lang="rsplus">zigzag2 <- function(n) {
a <- zigzag1(n)
v <- seq(n - 1)^2
for (i in seq(n - 1)) {
a[n - i + 1, seq(i + 1, n)] <- a[n - i + 1, seq(i + 1, n)] - v[seq(n - i)]
}
a
}
 
zigzag2(5)</syntaxhighlight>
 
{{out}}
 
<pre> [,1] [,2] [,3] [,4] [,5]
[1,] 0 1 5 6 14
[2,] 2 4 7 13 15
[3,] 3 8 12 16 21
[4,] 9 11 17 20 22
[5,] 10 18 19 23 24</pre>
 
=={{header|Racket}}==
<syntaxhighlight lang="racket">
#lang racket
 
(define/match (compare i j)
[((list x y) (list a b)) (or (< x a) (and (= x a) (< y b)))])
 
(define/match (key i)
[((list x y)) (list (+ x y) (if (even? (+ x y)) (- y) y))])
 
(define (zigzag-ht n)
(define indexorder
(sort (for*/list ([x n] [y n]) (list x y))
compare #:key key))
(for/hash ([(n i) (in-indexed indexorder)]) (values n i)))
(define (zigzag n)
(define ht (zigzag-ht n))
(for/list ([x n])
(for/list ([y n])
(hash-ref ht (list x y)))))
 
(zigzag 4)
</syntaxhighlight>
{{out}}
<pre>
'((0 2 3 9)
(1 4 8 10)
(5 7 11 14)
(6 12 13 15))
</pre>
 
=={{header|Raku}}==
(formerly Perl 6)
 
Using the same Turtle class as in the [[Spiral_matrix#Raku|Spiral matrix]] task:
 
<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" !! ' ';
}
}
}
 
sub MAIN(Int $size = 5) {
my $t = Turtle.new(dir => 1);
my $counter = 0;
for 1 ..^ $size -> $run {
for ^$run {
$t.lay-egg($counter++);
$t.forward;
}
my $yaw = $run %% 2 ?? -1 !! 1;
$t.turn-right($yaw * 135); $t.forward; $t.turn-right($yaw * 45);
}
for $size ... 1 -> $run {
for ^$run -> $ {
$t.lay-egg($counter++);
$t.forward;
}
$t.turn-left(180); $t.forward;
my $yaw = $run %% 2 ?? 1 !! -1;
$t.turn-right($yaw * 45); $t.forward; $t.turn-left($yaw * 45);
}
$t.showmap;
}</syntaxhighlight>
 
=={{header|Rascal}}==
{{incorrect|Rascal|Output is striped rather than zig-zag
i.e. your numbers always increase going diagonally down and to the left when it should alternativly increase/decrease.}}
This is a translation of the [[Zig-zag_matrix#Python|Python]] example.
As explained on the [[Talk:Zig-zag_matrix#anti-diagonals|Talk]] page,
the key way to understand a zig-zag matrix is to write down
an example with coordinates:
<syntaxhighlight lang="rascal">0 (0,0), 1 (0,1), 3 (0,2)
2 (1,0), 4 (1,1), 6 (1,2)
5 (2,0), 7 (2,1), 8 (2,2)</syntaxhighlight>
If you order these coordinates on the number, you create the order:
<syntaxhighlight lang="rascal"> 0 (0,0), 1 (0,1), 2 (1,0), 3 (0,2), 4 (1,1), 5 (2,0), 6 (1,2), 7 (2,1), 8 (2,2)</syntaxhighlight>
One can observe that this increases with the sum of the coordinates,
and secondly with the the first number of the coordinates.
The Rascal example uses this phenomenon:
<syntaxhighlight lang="rascal">import util::Math;
import List;
import Set;
import IO;
 
alias cd = tuple[int,int];
 
public rel[cd, int] zz(int n){
indexorder = sort([<x,y>| x <- [0..n], y <- [0..n]],
bool (cd a, cd b){
if (a[0]+a[1] > b[0]+b[1])
return false;
elseif(a[0] < b[0])
return false;
else
return true;
;
});
return {<indexorder[z] , z> | z <- index(indexorder)};
}
 
public void printzz(rel[cd, int] myarray){
n = floor(sqrt(size(myarray)));
for (x <- [0..n-1]){
for (y <- [0..n-1]){
print("<myarray[<y,x>]>\t");}
println();}
}</syntaxhighlight>
{{out}}
<pre>rascal>printzz(zz(4))
{0} {1} {3} {6} {10}
{2} {4} {7} {11} {15}
{5} {8} {12} {16} {19}
{9} {13} {17} {20} {22}
{14} {18} {21} {23} {24}
ok</pre>
 
=={{header|REXX}}==
This REXX version allows the optional specification of the &nbsp; '''start''' &nbsp; and &nbsp; '''increment''' &nbsp; values.
<lang rexx>
===Version 1===
/*REXX program to produce a zig-zag matrix (array) and display it. */
<syntaxhighlight lang="rexx">/*REXX program produces and displays a zig─zag matrix (a square array). */
row=1; col=1; parse arg n .; if n=='' then n=5 /*assume the default.*/
parse arg n start inc . /*obtain optional arguments from the CL*/
if n=='' | n=="," then n= 5 /*Not specified? Then use the default.*/
if start=='' | start=="," then start= 0 /* " " " " " " */
if inc=='' | inc=="," then inc= 1 /* " " " " " " */
row= 1; col= 1; size= n**2 /*start: 1st row & column; array size.*/
do j=start by inc for size; @.row.col= j
if (row+col)//2==0 then do; if col<n then col= col+1; else row= row+2
if row\==1 then row= row-1
end
else do; if row<n then row= row+1; else col= col+2
if col\==1 then col= col-1
end
end /*j*/ /* [↑] // is REXX ÷ remainder.*/
call show /*display a (square) matrix──►terminal.*/
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
show: w= max(length(start), length(start+size*inc)) /*max width of any matrix elements,*/
do r=1 for n ; _= right(@.r.1, w) /*show the rows of the matrix. */
do c=2 for n-1; _= _ right(@.r.c, w) /*build a line for output of a row.*/
end /*c*/; say _ /* [↑] align the matrix elements. */
end /*r*/; return</syntaxhighlight>
{{out|output|text=&nbsp; when using the default inputs:}}
<pre>
0 1 5 6 14
2 4 7 13 15
3 8 12 16 21
9 11 17 20 22
10 18 19 23 24
</pre>
{{out|output|text=&nbsp; when using the inputs of: &nbsp; &nbsp; <tt> 5 &nbsp; 1 </tt>}}
<pre>
1 2 6 7 15
3 5 8 14 16
4 9 13 17 22
10 12 18 21 23
11 19 20 24 25
</pre>
{{out|output|text=&nbsp; when using the inputs of: &nbsp; &nbsp; <tt> 4 &nbsp; -1000 &nbsp; -1 </tt>}}
<pre>
-1000 -1001 -1005 -1006
-1002 -1004 -1007 -1012
-1003 -1008 -1011 -1013
-1009 -1010 -1014 -1015
</pre>
 
===Version 2 - simplified logic===
do j=0 for n*n
<syntaxhighlight lang="rexx">/*REXX program produces and displays a zig-zag matrix (a square array) */
@.row.col=j
Parse Arg n start inc . /* obtain optional arguments from command line */
if (row+col)//2==0 then do
if n=='' | n=="," then n= 5 /*Not specified? use the if col<n then col=col+1; else row=row+2default*/
if start=='' | start=="," then start= 0 /* " " " " if row\==1 then row=row-1 " */
if inc=='' | inc=="," then inc= 1 /* " " end " " " */
Parse Value 1 1 n**2 With row col size
else do
Do x=start By inc For size
if row<n then row=row+1; else col=col+2
m.row.col=x
if col\==1 then col=col-1
If (row+col)//2=0 Then do /* moving upward end */
Select
end
when row=1 Then Do /* at upper bound */
If col<n Then
col=col+1 /* move right */
Else
row=2 /* move down */
End
when col=n Then /* at right border */
row=row+1 /* move down */
Otherwise Do /* in all other cases */
row=row-1 /* move up */
col=col+1 /* and to the right */
End
End
End
Else Do /* moving downward */
Select
When col=1 Then Do /* at lower bound */
If row=n Then /* in bottom row */
col=2 /* move right */
Else /* otherwise */
row=row+1 /* move down */
End
When row=n Then /* at lower bound */
col=col+1 /* move right */
Otherwise Do /* in all other cases */
row=row+1 /* move down */
col=col-1 /* and to the left */
End
End
End
End
Call show
Exit
/*-----------------------------------------------------------------------*/
show:
w=length(start+size*inc) /* max width of any matrix element */
Do row=1 To n /* loop over rows */
line=right(m.row.1,w) /* first element */
Do column=2 To n /* loop over other elements */
line=line right(m.row.column,w) /* build output line */
End
Say line
End /* display the line */
Return</syntaxhighlight>
 
=={{header|Ring}}==
L=length(n*n-1) /*for a constant element width. */
<syntaxhighlight lang="ring">
do row=1 for n /*show all the matrix's rows. */
# Project Zig-zag matrix
_=''
 
do col=1 for n; _=_ right(@.row.col,L); end
load "guilib.ring"
say _
load "stdlib.ring"
end
new qapp
</lang>
{
Output when using the default of 5:
win1 = new qwidget() {
<pre style="height:15ex;overflow:scroll">
setwindowtitle("Zig-zag matrix")
0 1 5 6 14
setgeometry(100,100,600,400)
2 4 7 13 15
3 8 12 16 21 n = 5
a = newlist(n,n)
9 11 17 20 22
zigzag = newlist(n,n)
10 18 19 23 24
for j = 1 to n
for i = 1 to n
a[j][i] = 0
next
next
i = 1
j = 1
k = 1
while k < n * n
a[j][i] = k
k = k + 1
if i = n
j = j + 1
a[j][i] = k
k = k + 1
di = -1
dj = 1
ok
if j = 1
i = i + 1
a[j][i] = k
k = k + 1
di = -1
dj = 1
ok
if j = n
i = i + 1
a[j][i] = k
k = k + 1
di = 1
dj = -1
ok
if i = 1
j = j + 1
a[j][i] = k
k = k + 1
di = 1
dj = -1
ok
i = i + di
j = j + dj
end
for p = 1 to n
for m = 1 to n
zigzag[p][m] = new qpushbutton(win1) {
x = 150+m*40
y = 30 + p*40
setgeometry(x,y,40,40)
settext(string(a[p][m]))
}
next
next
show()
}
exec()
}
</syntaxhighlight>
Output:
 
[http://kepkezelo.com/images/kk86ng7p4gcl7z3p7vo1.jpg Zig-Zag matrix]
 
=={{header|RPL}}==
{{works with|RPL|HP-48}}
Turtle's way.
« 1 -1 → n way val
« n DUP 2 →LIST 0 CON
2 n DUP + '''FOR''' s
n s 1 - MIN s OVER -
'''IF''' way 0 > '''THEN''' SWAP '''END'''
'''FOR''' j
j s OVER - 2 →LIST 'val' INCR PUT
way '''STEP'''
'way' SNEG
'''NEXT'''
» » '<span style="color:blue">ZIGZAG</span>' STO
 
6 <span style="color:blue">ZIGZAG</span>
{{out}}
<pre>
1: [[0 2 3 9 10 20]
[1 4 8 11 19 21]
[5 7 12 18 22 29]
[6 13 17 23 28 30]
[14 16 24 27 31 34]
[15 25 26 32 33 35]]
</pre>
 
=={{header|Ruby}}==
Using the print_matrix method from [[Reduced row echelon form#Ruby]]
 
{{trans|Python}}
<langsyntaxhighlight lang="ruby">def zigzag(n)
(seq=*0...n).product(seq)
indices = []
n.times {|x| n.timessort_by {|x,y| indices << [x+y, (x+y]).even? }? y : -y]}
.each_with_index.sort.map(&:last).each_slice(n).to_a
zigzag = Array.new(n) {Array.new(n, nil)} # n x n array of nils
indices.sort_by {|x,y| [x+y, ((x+y)%2).zero? ? y : -y]} \
.each_with_index {|a,i| x,y = a; zigzag[x][y] = i}
zigzag
end
 
print_matrix zigzag(5)</lang>
def print_matrix(m)
<pre> 0 1 5 6 14
format = "%#{m.flatten.max.to_s.size}d " * m[0].size
puts m.map {|row| format % row}
end
 
print_matrix zigzag(5)</syntaxhighlight>
{{out}}
<pre>
0 1 5 6 14
2 4 7 13 15
3 8 12 16 21
9 11 17 20 22
10 18 19 23 24</pre>
</pre>
 
=={{header|Rust}}==
<syntaxhighlight lang="rust">
use std::cmp::Ordering;
use std::cmp::Ordering::{Equal, Greater, Less};
use std::iter::repeat;
 
#[derive(Debug, PartialEq, Eq)]
struct SortIndex {
x: usize,
y: usize,
}
 
impl SortIndex {
fn new(x: usize, y: usize) -> SortIndex {
SortIndex { x, y }
}
}
 
impl PartialOrd for SortIndex {
fn partial_cmp(&self, other: &SortIndex) -> Option<Ordering> {
Some(self.cmp(other))
}
}
 
impl Ord for SortIndex {
fn cmp(&self, other: &SortIndex) -> Ordering {
let lower = if self.x + self.y == other.x + other.y {
if (self.x + self.y) % 2 == 0 {
self.x < other.x
} else {
self.y < other.y
}
} else {
(self.x + self.y) < (other.x + other.y)
};
 
if lower {
Less
} else if self == other {
Equal
} else {
Greater
}
}
}
 
fn zigzag(n: usize) -> Vec<Vec<usize>> {
let mut l: Vec<SortIndex> = (0..n * n).map(|i| SortIndex::new(i % n, i / n)).collect();
l.sort();
 
let init_vec = vec![0; n];
let mut result: Vec<Vec<usize>> = repeat(init_vec).take(n).collect();
for (i, &SortIndex { x, y }) in l.iter().enumerate() {
result[y][x] = i
}
result
}
 
fn main() {
println!("{:?}", zigzag(5));
}
 
</syntaxhighlight>
{{out}}
<pre>
[[0, 1, 5, 6, 14], [2, 4, 7, 13, 15], [3, 8, 12, 16, 21], [9, 11, 17, 20, 22], [10, 18, 19, 23, 24]]
</pre>
 
=={{header|Scala}}==
Uses the array indices sort solution used by others here.
 
<langsyntaxhighlight lang="scala"> def zigzag(n:int Int): Array[Array[Int]] = {
val l = for (i <- 0 until n*n) yield (i%n, i/n)
var l = List[Tuple2[int,int]]()
val lSorted = l.sortWith {
(0 until n*n) foreach {i=>l = l + (i%n,i/n)}
l = l.sort{ case ((x,y), (u,v)) => if (x+y == u+v)
if ((x+y) % 2 == 0) x<u else y<+v)
if ((x+y) % 2 == 0) x<u else (x+y) < (u+v) }
else x+y < u+v
var a = new Array[Array[int]](n,n)
}
l.zipWithIndex foreach {case ((x,y),i) => a(y)(x) = i}
val res = Array.ofDim[Int](n, n)
a
lSorted.zipWithIndex foreach {
}</lang>
case ((x,y), i) => res(y)(x) = i
}
res
}
zigzag(5).foreach{
ar => ar.foreach(x => print("%3d".format(x)))
println
}</syntaxhighlight>
Output:
<pre> 0 1 5 6 14
2 4 7 13 15
3 8 12 16 21
9 11 17 20 22
10 18 19 23 24
</pre>
 
=={{header|Scilab}}==
Or, compressed into just one statement
{{trans|Octave}}
 
<syntaxhighlight lang="scilab">function a = zigzag3(n)
<lang scala>def zigzag(n:int) = {
a = zeros(n, n)
var indices = List[Tuple2[Int,Int]]()
for k=1:n
var array = new Array[Array[Int]](n,n)
j = modulo(k, 2)
d = (2*j-1)*(n-1)
m = (n-1)*(k-1)
a(k+(1-j)*m:d:k+j*m) = k*(k-1)/2:k*(k+1)/2-1
a(n*(n+1-k)+(1-j)*m:d:n*(n+1-k)+j*m) = n*n-k*(k+1)/2:n*n-k*(k-1)/2-1
end
endfunction
 
-->zigzag3(5)
(0 until n*n).foldLeft(indices)((l,i) => l + (i%n,i/n)).
ans =
sort{case ((x,y),(u,v)) => if (x+y == u+v)
if ((x+y) % 2 == 0) x<u else y<v
0. 1. 5. 6. 14. else (x+y) < (u+v) }.
2. 4. 7. 13. 15.
zipWithIndex.foldLeft(array) {case (a,((x,y),i)) => a(y)(x) = i; a}
3. 8. 12. 16. 21.
}
9. 11. 17. 20. 22.
</lang>
10. 18. 19. 23. 24.</syntaxhighlight>
 
=={{header|Seed7}}==
<langsyntaxhighlight lang="seed7">$ include "seed7_05.s7i";
 
const type: matrix is array array integer;
Line 2,423 ⟶ 6,241:
writeln;
end for;
end func;</langsyntaxhighlight>
 
{{out}}
Output:
<pre>
1 2 6 7 15 16 28
Line 2,435 ⟶ 6,253:
22 34 35 43 44 48 49
</pre>
 
=={{header|Sidef}}==
{{trans|Perl}}
<syntaxhighlight lang="ruby">func zig_zag(w, h) {
 
var r = []
var n = 0
 
h.of { |e|
w.of { |f|
[e, f]
}
}.reduce('+').sort { |a, b|
(a[0]+a[1] <=> b[0]+b[1]) ||
(a[0]+a[1] -> is_even ? a[0]<=>b[0]
: a[1]<=>b[1])
}.each { |a|
r[a[1]][a[0]] = n++
}
 
return r
}
 
zig_zag(5, 5).each { say .join('', {|i| "%4i" % i}) }</syntaxhighlight>
{{out}}
<pre>
0 1 5 6 14
2 4 7 13 15
3 8 12 16 21
9 11 17 20 22
10 18 19 23 24
</pre>
 
=={{header|Standard ML}}==
<syntaxhighlight lang="standard ml">fun rowprint r = (List.app (fn i => print (StringCvt.padLeft #" " 3 (Int.toString i))) r;
print "\n");
fun zig lst M = List.app rowprint (lst M);
 
fun sign t = if t mod 2 = 0 then ~1 else 1;
 
fun zag n = List.tabulate (n,
fn i=> rev ( List.tabulate (n,
fn j =>
let val t = n-j+i and u = n+j-i in
if i <= j
then t*t div 2 + sign t * ( t div 2 - i )
else n*n - 1 - ( u*u div 2 + sign u * ( u div 2 - n + 1 + i) )
end
)));
 
zig zag 5 ;</syntaxhighlight>
0 1 5 6 14
2 4 7 13 15
3 8 12 16 21
9 11 17 20 22
10 18 19 23 24
val it = () : unit
 
 
 
=={{header|Stata}}==
The requested zig-zag matrix can be constructed as a correction of another zig-zag matrix, which is a square "view" of the infinite zig-zag matrix. Here is the latter:
 
<syntaxhighlight lang="stata">function zigzag1(n) {
j = 0::n-1
u = J(1, n, (-1, 1))
v = (j:*(2:*j:+3))
v = rowshape((v,v:+1), 1)
a = J(n, n, .)
for (i=1; i<=n; i++) {
a[i, .] = v[j:+i]
v = v+u
}
return(a)
}
 
zigzag1(5)
1 2 3 4 5
+--------------------------+
1 | 0 1 5 6 14 |
2 | 2 4 7 13 16 |
3 | 3 8 12 17 25 |
4 | 9 11 18 24 31 |
5 | 10 19 23 32 40 |
+--------------------------+</syntaxhighlight>
 
Now the corrected matrix, which solves the task:
 
<syntaxhighlight lang="stata">function zigzag2(n) {
a = zigzag1(n)
v = (1..n-1):^2
for (i=1; i<n; i++) {
a[n-i+1, i+1..n] = a[n-i+1, i+1..n] - v[1..n-i]
}
return(a)
}
 
zigzag2(5)
1 2 3 4 5
+--------------------------+
1 | 0 1 5 6 14 |
2 | 2 4 7 13 15 |
3 | 3 8 12 16 21 |
4 | 9 11 17 20 22 |
5 | 10 18 19 23 24 |
+--------------------------+</syntaxhighlight>
 
The correction is given by the difference:
 
<syntaxhighlight lang="stata">zigzag1(5)-zigzag2(5)
[symmetric]
1 2 3 4 5
+--------------------------+
1 | 0 |
2 | 0 0 |
3 | 0 0 0 |
4 | 0 0 1 4 |
5 | 0 1 4 9 16 |
+--------------------------+</syntaxhighlight>
 
=={{header|Tcl}}==
Using <code>print_matrix</code> from [[Matrix Transpose#Tcl|Matrix Transpose]]…
<langsyntaxhighlight lang="tcl">proc zigzag {size} {
set m [lrepeat $size [lrepeat $size .]]
set x 0; set dx -1
Line 2,473 ⟶ 6,410:
}
 
print_matrix [zigzag 5]</langsyntaxhighlight>
{{out}}
<pre> 0 1 5 6 14
2 4 7 13 15
Line 2,479 ⟶ 6,417:
9 11 17 20 22
10 18 19 23 24</pre>
 
=={{header|uBasic/4tH}}==
{{trans|BBC BASIC}}
<syntaxhighlight lang="ubasic">S = 5
 
i = 1
j = 1
 
For e = 0 To (S*S)-1
@((i-1) * S + (j-1)) = e
 
If (i + j) % 2 = 0 Then
 
If j < S Then
j = j + 1
Else
i = i + 2
EndIf
 
If i > 1 Then
i = i - 1
EndIf
Else
 
If i < S
i = i + 1
Else
j = j + 2
EndIf
 
If j > 1
j = j - 1
EndIf
EndIf
Next
 
For r = 0 To S-1
For c = 0 To S-1
Print Using "___#";@(r * S + c);
Next
Print
Next</syntaxhighlight>
{{out}}
<pre> 0 1 5 6 14
2 4 7 13 15
3 8 12 16 21
9 11 17 20 22
10 18 19 23 24
 
0 OK, 0:428</pre>
 
=={{header|Ursala}}==
adapted from the J solution
<langsyntaxhighlight Ursalalang="ursala">#import std
#import nat
 
zigzag = ~&mlPK2xnSS+ num+ ==+sum~~|=xK9xSL@iiK0+ iota</langsyntaxhighlight>
test program (three examples):
<langsyntaxhighlight Ursalalang="ursala">#cast %nLLL
 
tests = zigzag* <4,5,6></langsyntaxhighlight>
{{out}}
output:
<pre><
<
Line 2,512 ⟶ 6,500:
 
=={{header|VBA}}==
<langsyntaxhighlight lan= VBA>
Public Sub zigzag(n)
Dim a() As Integer
Line 2,572 ⟶ 6,560:
Next
End Sub
</syntaxhighlight>
</lang>
 
{{out}}
Output:
<pre>
zigzag 5
Line 2,592 ⟶ 6,580:
10 19 22 28 31 33
20 21 29 30 34 35
</pre>
 
=={{header|VBScript}}==
{{trans|BBC BASIC}}
<syntaxhighlight lang="vb">ZigZag(Cint(WScript.Arguments(0)))
 
Function ZigZag(n)
Dim arrZ()
ReDim arrZ(n-1,n-1)
i = 1
j = 1
For e = 0 To (n^2) - 1
arrZ(i-1,j-1) = e
If ((i + j ) And 1) = 0 Then
If j < n Then
j = j + 1
Else
i = i + 2
End If
If i > 1 Then
i = i - 1
End If
Else
If i < n Then
i = i + 1
Else
j = j + 2
End If
If j > 1 Then
j = j - 1
End If
End If
Next
For k = 0 To n-1
For l = 0 To n-1
WScript.StdOut.Write Right(" " & arrZ(k,l),3)
Next
WScript.StdOut.WriteLine
Next
End Function</syntaxhighlight>
 
{{out}}
<pre>
C:\>cscript /nologo ZigZag.vbs 5
0 1 5 6 14
2 4 7 13 15
3 8 12 16 21
9 11 17 20 22
10 18 19 23 24
 
C:\>cscript /nologo ZigZag.vbs 7
0 1 5 6 14 15 27
2 4 7 13 16 26 28
3 8 12 17 25 29 38
9 11 18 24 30 37 39
10 19 23 31 36 40 45
20 22 32 35 41 44 46
21 33 34 42 43 47 48
</pre>
 
=={{header|Wren}}==
{{trans|Go}}
{{libheader|Wren-fmt}}
<syntaxhighlight lang="wren">import "./fmt" for Conv, Fmt
 
var zigzag = Fn.new { |n|
var r = List.filled(n*n, 0)
var i = 0
var n2 = n * 2
for (d in 1..n2) {
var x = d - n
if (x < 0) x = 0
var y = d - 1
if (y > n - 1) y = n - 1
var j = n2 - d
if (j > d) j = d
for (k in 0...j) {
if (d&1 == 0) {
r[(x+k)*n+y-k] = i
} else {
r[(y-k)*n+x+k] = i
}
i = i + 1
}
}
return r
}
 
var n = 5
var w = Conv.itoa(n*n - 1).count
var i = 0
for (e in zigzag.call(n)) {
Fmt.write("$*d ", w, e)
if (i%n == n - 1) System.print()
i = i + 1
}</syntaxhighlight>
 
{{out}}
<pre>
0 1 5 6 14
2 4 7 13 15
3 8 12 16 21
9 11 17 20 22
10 18 19 23 24
</pre>
 
=={{header|XPL0}}==
<syntaxhighlight lang="xpl0">include c:\cxpl\codes;
def N=6;
int A(N,N), X, Y, I, D;
[I:=0; X:=0; Y:=0; D:=1;
repeat A(X,Y):=I;
case of
X+D>=N: [D:=-D; Y:=Y+1];
Y-D>=N: [D:=-D; X:=X+1];
X+D<0: [D:=-D; Y:=Y+1];
Y-D<0: [D:=-D; X:=X+1]
other [X:=X+D; Y:=Y-D];
I:=I+1;
until I>=N*N;
for Y:=0 to N-1 do
[for X:=0 to N-1 do
[I:=A(X,Y);
ChOut(0,^ );
if I<10 then ChOut(0,^ );
IntOut(0, I);
];
CrLf(0);
];
]</syntaxhighlight>
 
{{out}}
<pre>
0 1 5 6 14 15
2 4 7 13 16 25
3 8 12 17 24 26
9 11 18 23 27 32
10 19 22 28 31 33
20 21 29 30 34 35
</pre>
 
=={{header|Yabasic}}==
<syntaxhighlight lang="yabasic">Size = 5
DIM array(Size-1, Size-1)
 
i = 1
j = 1
FOR e = 0 TO Size^2-1
array(i-1, j-1) = e
IF and((i + j), 1) = 0 THEN
IF j < Size then j = j + 1 ELSE i = i + 2 end if
IF i > 1 i = i - 1
ELSE
IF i < Size then i = i + 1 ELSE j = j + 2 end if
IF j > 1 j = j - 1
ENDIF
NEXT e
 
FOR row = 0 TO Size-1
FOR col = 0 TO Size-1
PRINT array(row,col) USING "##";
NEXT col
PRINT
NEXT row</syntaxhighlight>
 
=={{header|zkl}}==
{{trans|Groovy}}
<syntaxhighlight lang="zkl">fcn zz(n){
grid := (0).pump(n,List, (0).pump(n,List).copy).copy();
ri := Ref(0);
foreach d in ([1..n*2]){
x:=(0).max(d - n); y:=(n - 1).min(d - 1);
(0).pump(d.min(n*2 - d),Void,'wrap(it){
grid[if(d%2)y-it else x+it][if(d%2)x+it else y-it] = ri.inc();
});
}
grid.pump(String,'wrap(r){("%3s"*n+"\n").fmt(r.xplode())});
}</syntaxhighlight>
{{trans|C}}
Using list comprehension (and side effects) for the double loop,
the resulting list is just thrown away,
which is easier than creating an enumerated list and sorting.
<syntaxhighlight lang="zkl">fcn ceg(m){
s := (0).pump(m*m,List).copy(); // copy to make writable
rn := Ref(0);
[[(i,j); [0..m*2-1]; '{[(0).max(i-m+1) .. i.min(m-1)]};
'{ s[ if(i.isOdd) j*(m-1)+i else (i-j)*m+j ] = rn.inc(); }]];
s.pump(String,T(Void.Read,m-1), ("%3s"*m+"\n").fmt);
}</syntaxhighlight>
To be pedantic, the same as above,
but using the output of the list comprehension:
<syntaxhighlight lang="zkl">fcn ceg2(m){
rn := Ref(0);
[[(i,j); [0..m*2-1]; '{[(0).max(i-m+1) .. i.min(m-1)]};
'{ T( if(i.isOdd) j*(m-1)+i else (i-j)*m+j;, rn.inc() ) }]]
.sort(fcn([(a,_)], [(b,_)]){ a<b }).apply("get",1)
.pump(String,T(Void.Read,m-1), ("%3s"*m+"\n").fmt);
}</syntaxhighlight>
{{out}} The results are the same:
<pre>
zz(5).println();
0 1 5 6 14
2 4 7 13 15
3 8 12 16 21
9 11 17 20 22
10 18 19 23 24
</pre>
1,150

edits