# Zig-zag matrix

Zig-zag matrix
You are encouraged to solve this task according to the task description, using any language you may know.

Produce a zig-zag array.

A   zig-zag   array is a square arrangement of the first   N2   integers,   where the
numbers increase sequentially as you zig-zag along the array's   anti-diagonals.

For a graphical representation, see   JPG zigzag   (JPG uses such arrays to encode images).

For example, given   5,   produce this array:

 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


## 360 Assembly

*        Zig-zag matrix            15/08/2015ZIGZAGMA 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=0LOOPK    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      EIF1ELSE1    LA     R6,2(R6)           i=i+2EIF1     CH     R6,=H'1'           if i>1         BNH    NOT1         BCTR   R6,0               i=i-1NOT1     B      NOT2ELSEMOD  CR     R6,R9              if i<n         BNL    ELSE2         LA     R6,1(R6)           i=i+1         B      EIF2ELSE2    LA     R7,2(R7)           j=j+2EIF2     CH     R7,=H'1'           if j>1         BNH    NOT2         BCTR   R7,0               j=j-1NOT2     LA     R8,1(R8)           k=k+1         B      LOOPKELOOPK   LA     R6,1               end k; i=1LOOPI    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=1LOOPJ    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      LOOPJELOOPJ   XPRNT  BUFFER,80          end j         LA     R6,1(R6)           i=i+1         B      LOOPIELOOPI   XR     R15,R15            end i; return_code=0         BR     R14                return to callerN        EQU    5                  matrix sizeBUFFER   DS     CL80XDEC     DS     CL12T        DS     (N*N)H             t(n,n) matrix          YREGS         END    ZIGZAGMA
Output:
   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


## ActionScript

 package {   public class ZigZagMatrix extends Array   {       private var height:uint;      private var width:uint;      public var mtx:Array = [];       public function ZigZagMatrix(size:uint)      {         this.height = size;         this.width = size;          this.mtx = [];         for (var i:uint = 0; i < size; i++) {             this.mtx[i] = [];         }         i = 1;         var j:uint = 1;          for (var e:uint = 0; e < size*size; e++) {            this.mtx[i-1][j-1] = e;            if ((i + j) % 2 == 0) {               // Even stripes               if (j < size) j ++;               else       i += 2;               if (i > 1) i --;            } else {               // Odd stripes               if (i < size) i ++;               else       j += 2;               if (j > 1) j --;            }         }      }     }  }

with Ada.Text_IO;  use Ada.Text_IO; procedure Test_Zig_Zag is    type Matrix is array (Positive range <>, Positive range <>) of Natural;   function Zig_Zag (Size : Positive) return Matrix is      Data : Matrix (1..Size, 1..Size);      I, J : Integer := 1;   begin      Data (1, 1) := 0;      for Element in 1..Size**2 - 1 loop         if (I + J) mod 2 = 0 then            -- Even stripes            if J < Size then               J := J + 1;            else               I := I + 2;            end if;            if I > 1 then               I := I - 1;            end if;         else            -- Odd stripes            if I < Size then               I := I + 1;            else               J := J + 2;            end if;            if J > 1 then               J := J - 1;            end if;         end if;         Data (I, J) := Element;      end loop;      return Data;   end Zig_Zag;    procedure Put (Data : Matrix) is   begin      for I in Data'Range (1) loop         for J in Data'Range (2) loop            Put (Integer'Image (Data (I, J)));         end loop;         New_Line;      end loop;   end Put; begin   Put (Zig_Zag (5));end Test_Zig_Zag;

The function Zig_Zag generates a square matrix filled as requested by the task.

Output:
 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


## Agena

Tested with Agena 2.9.5 Win32

# 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 resultend; scope    local m := makeZigZag( 5 );    for i to size m do        for j to size m do            printf( " %3d", m[ i, j ] )        od;        print()    odepocs
Output:
   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


## ALGOL 68

Translation of: D
Works with: ALGOL 68 version Standard - no extensions to language used
Works with: ALGOL 68G version Any - tested with release mk15-0.8b.fc9.i386
Works with: ELLA ALGOL 68 version Any (with appropriate job cards) - tested with release 1.8.8d.fc9.i386
PROC zig zag = (INT n)[,]INT: (    PROC move = (REF INT i, j)VOID: (        IF j < n THEN            i := ( i <= 1 | 1 | i-1 );            j +:= 1        ELSE            i +:= 1        FI    );     [n, n]INT a;    INT x:=LWB a, y:=LWB a;     FOR v FROM 0 TO n**2-1 DO        a[y, x] := v;        IF ODD (x + y) THEN            move(x, y)        ELSE            move(y, x)        FI    OD;    a); INT dim = 5;#IF formatted transput possible THEN  FORMAT d = $z-d$;  FORMAT row = $"("n(dim-1)(f(d)",")f(d)")"$;  FORMAT block = $"("n(dim-1)(f(row)","lx)f(row)")"l$;   printf((block, zig zag(dim)))ELSE#  [,]INT result = zig zag(dim);  FOR i TO dim DO    print((result[i,], new line))  OD#FI#
Output:
 With formatted transput possible, e.g. ALGOL 68G not formatted transput possible, e.g. ELLA ALGOL 68 (( 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 +2 +4 +7 +13 +15 +3 +8 +12 +16 +21 +9 +11 +17 +20 +22 +10 +18 +19 +23 +24 

## ALGOL W

Based on the Agena sample.

begin % zig-zag matrix %    % z is returned holding a zig-zag matrix of order n, z must be at least n x n %    procedure makeZigZag ( integer value n                         ; 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.
Output:
   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


## APL

Works with: Dyalog APL
Translation of: J
      zz   ←  {⍵⍴⎕IO-⍨⍋⊃,/{(2|⍴⍵):⌽⍵⋄⍵}¨(⊂w)/¨⍨w{↓⍵∘.=⍨∪⍵}+/[1]⍵⊤w←⎕IO-⍨⍳×/⍵}   ⍝  General zigzag (any rectangle)      zzSq ←  {zz,⍨⍵}                                                           ⍝  Square zigzag      zzSq 5 0  1  5  6 14 2  4  7 13 15 3  8 12 16 21 9 11 17 20 2210 18 19 23 24

## AppleScript

### Iterative

Here's a vector & matrix boundary detection approach to the Zig-zap matrix:

set n to 5 -- Size of zig-zag matrix (n^2 cells). -- Create an empty matrix.set m to {}repeat with i from 1 to n	set R to {}	repeat with j from 1 to n		set end of R to 0	end repeat	set end of m to Rend repeat -- Populate the matrix in a zig-zag manner.set {x, y, v, d} to {1, 1, 0, 1}repeat while v < (n ^ 2)	if 1 ≤ x and x ≤ n and 1 ≤ y and y ≤ n then		set {m's item y's item x, x, y, v} to {v, x + d, y - d, v + 1}	else if x > n then		set {x, y, d} to {n, y + 2, -d}	else if y > n then		set {x, y, d} to {x + 2, n, -d}	else if x < 1 then		set {x, y, d} to {1, y, -d}	else if y < 1 then		set {x, y, d} to {x, 1, -d}	end ifend repeat--> R = {{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}} -- Reformat the matrix into a table for viewing. repeat with i in m	repeat with j in i		set j's contents to  (characters -(length of (n ^ 2 as string)) thru -1 of ("          " & j)) as string	end repeat	set end of i to returnend repeatreturn return & m as string
But this can be improved upon by building the matrix by populating empty AppleScript lists (it's about 50% faster when n=50):
set n to 5 set m to {}repeat with i from 1 to n	set end of m to {} -- Built a foundation for the matrix out of n empty lists.end repeat set {v, d, i} to {0, -1, 1}repeat while v < n ^ 2	if length of m's item i < n then		set {end of m's item i, i, v} to {f(v, n), i + d, v + 1}		if i < 1 then			set {i, d} to {1, -d}		else if i > n then			set {i, d} to {n, -d}		else if i > 1 and (count of m's item (i - 1)) = 1 then			set d to -d		end if	else		set {i, d} to {i + 1, 1}	end ifend repeat -- Handler/function to format the cells on the fly.on f(v, n)	return (characters -(length of (n ^ 2 as string)) thru -1 of ("          " & v)) as stringend f -- Reformat the matrix into a table for viewing. set text item delimiters to ""repeat with i in m	set i's contents to (i as string) & returnend repeatreturn return & m as string
Output:
for both scripts is:
"
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

"

### Recursive

By functional composition:

-- zigzagMatrixon 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 ifend 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 lstend 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 tellend filter -- head :: [a] -> aon head(xs)    if length of xs > 0 then        item 1 of xs    else        missing value    end ifend 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 tellend map -- Lift 2nd class handler function into 1st class script wrapper -- mReturn :: Handler -> Scripton mReturn(f)    if class of f is script then        f    else        script            property |λ| : f        end script    end ifend 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 ifend splitAt -- tail :: [a] -> [a]on tail(xs)    if length of xs > 1 then        items 2 thru -1 of xs    else        {}    end ifend tail
Output:
{{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}}

## 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)}
Output:
  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


## BBC BASIC

      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%
Output:
   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


## 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.

>> 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>#^[email protected]^!g03g00!g04++**2p03:+1g03!\*+1*2g01:g04.$<
Output:
 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

#include <stdio.h>#include <stdlib.h> int main(int c, char **v){	int i, j, m, n, *s; 	/* default size: 5 */	if (c < 2 || ((m = atoi(v[1]))) <= 0) m = 5; 	/* alloc array*/	s = malloc(sizeof(int) * m * m); 	for (i = n = 0; i < m * 2; i++)		for (j = (i < m) ? 0 : i-m+1; j <= i && j < m; j++)			s[(i&1)? j*(m-1)+i : (i-j)*m+j ] = n++; 	for (i = 0; i < m * m; putchar((++i % m) ? ' ':'\n'))		printf("%3d", s[i]); 	/* free(s) */	return 0;}
Output:
% ./a.out 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

## C++

#include <vector>#include <memory>	// for auto_ptr#include <cmath>	// for the log10 and floor functions#include <iostream>#include <iomanip>	// for the setw function using namespace std; typedef vector< int > IntRow;typedef vector< IntRow > IntTable; auto_ptr< IntTable > getZigZagArray( int dimension ){	auto_ptr< IntTable > zigZagArrayPtr( new IntTable(		dimension, IntRow( dimension ) ) ); 	// fill along diagonal stripes (oriented as "/")	int lastValue = dimension * dimension - 1;	int currNum = 0;	int currDiag = 0;	int loopFrom;	int loopTo;	int i;	int row;	int col;	do	{		if ( currDiag < dimension ) // if doing the upper-left triangular half		{			loopFrom = 0;			loopTo = currDiag;		}		else // doing the bottom-right triangular half		{			loopFrom = currDiag - dimension + 1;			loopTo = dimension - 1;		} 		for ( i = loopFrom; i <= loopTo; i++ )		{			if ( currDiag % 2 == 0 ) // want to fill upwards			{				row = loopTo - i + loopFrom;				col = i;			}			else // want to fill downwards			{				row = i;				col = loopTo - i + loopFrom;			} 			( *zigZagArrayPtr )[ row ][ col ] = currNum++;		} 		currDiag++;	}	while ( currDiag <= lastValue ); 	return zigZagArrayPtr;} void printZigZagArray( const auto_ptr< IntTable >& zigZagArrayPtr ){	size_t dimension = zigZagArrayPtr->size(); 	int fieldWidth = static_cast< int >( floor( log10(		static_cast< double >( dimension * dimension - 1 ) ) ) ) + 2; 	size_t col;	for ( size_t row = 0; row < dimension; row++ )	{		for ( col = 0; col < dimension; col++ )			cout << setw( fieldWidth ) << ( *zigZagArrayPtr )[ row ][ col ];		cout << endl;	}} int main(){	printZigZagArray( getZigZagArray( 5 ) );}
Output:
  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#

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;}

## 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() {	value zz = ZigZag(5);	zz.display();}

## Clojure

Purely functional approach.

(defn partitions [sizes coll]  (lazy-seq   (when-let [n (first sizes)]     (when-let [s (seq coll)]       (cons (take n coll)	     (partitions (next sizes) (drop n coll))))))) (defn take-from [n colls]  (lazy-seq   (when-let [s (seq colls)]     (let [[first-n rest-n] (split-at n s)]       (cons (map first first-n)	     (take-from n (concat (filter seq (map rest first-n)) rest-n))))))) (defn zig-zag [n]  (->> (partitions (concat (range 1 (inc n)) (range (dec n) 0 -1)) (range (* n n)))       (map #(%1 %2) (cycle [reverse identity]) ,)       (take-from n ,))) user> (zig-zag 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)) user> (zig-zag 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))

## 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" 
Output:
> 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 ] ]


## Common Lisp

### Translation of: Java (but with zero-based indexes and combining the even and odd cases)

(defun zigzag (n)  (flet ((move (i j)           (if (< j (1- n))               (values (max 0 (1- i)) (1+ j))               (values (1+ i) j))))    (loop with a = (make-array (list n n) :element-type 'integer)          with x = 0          with y = 0          for v from 0 below (* n n)          do (setf (aref a x y) v)             (if (evenp (+ x y))                 (setf (values x y) (move x y))                 (setf (values y x) (move y x)))          finally (return a))))

### An alternative approach

 ; 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)))))))  

(ZigZag 5) Produces:

  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


(ZigZag 8) Produces:

  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


(ZigZag 9) Produces:

  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


## D

Translation of: Common Lisp
int[][] zigZag(in int n) pure nothrow @safe {    static void move(in int n, ref int i, ref int j)    pure nothrow @safe @nogc {        if (j < n - 1) {            if (i > 0) i--;            j++;        } else            i++;    }     auto a = new int[][](n, n);    int x, y;    foreach (v; 0 .. n ^^ 2) {        a[y][x] = v;        (x + y) % 2 ? move(n, x, y) : move(n, y, x);    }    return a;} void main() {    import std.stdio;     writefln("%(%(%2d %)\n%)", 5.zigZag);}
Output:
 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

### Alternative Version

Translation of: Scala

Same output.

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);}

## E

First, some tools originally written for Spiral (only the array is used):

/** Missing scalar multiplication, but we don't need it. */def makeVector2(x, y) {  return def vector {    to x() { return x }    to y() { return y }    to add(other) { return makeVector2(x + other.x(), y + other.y()) }    to clockwise() { return makeVector2(-y, x) }  }} /** Bugs: (1) The printing is specialized. (2) No bounds check on the column. */def makeFlex2DArray(rows, cols) {  def storage := ([null] * (rows * cols)).diverge()  return def flex2DArray {    to __printOn(out) {      for y in 0..!rows {        for x in 0..!cols {          out.print(<import:java.lang.makeString>.format("%3d", [flex2DArray[y, x]]))        }        out.println()      }    }    to get(r, c) { return storage[r * cols + c] }    to put(r, c, v) { storage[r * cols + c] := v }  }}
Then the code.
Translation of: D
def zigZag(n) {  def move(&i, &j) {      if (j < (n - 1)) {          i := 0.max(i - 1)          j += 1      } else {          i += 1      }  }   def array := makeFlex2DArray(n, n)  var x := 0  var y := 0   for i in 1..n**2 {      array[y, x] := i      if ((x + y) % 2 == 0) {          move(&x, &y)      } else {          move(&y, &x)      }  }  return array}

## Elena

Translation of: C#

ELENA 3.4:

import extensions. extension<int> op{    zigzagMatrix    [        auto result := IntMatrix new(self, self).         int i := 0.        int j := 0.        int d := -1.        int start := 0.        int end := self*self - 1.         while (start < end)        [            result write(i, j, start). start += 1.            result write(self - i - 1, self - j - 1, end). end -= 1.             i := i + d.            j := j - d.            if (i < 0)            [                i:=i+1. d := d negative            ];            [                if (j < 0)                [                    j := j + 1. d := d negative                ]            ]        ].         if (start == end)        [            result write(i, j, start).        ].         ^ result    ]} public program[    console printLine(5 zigzagMatrix); readChar.]

## 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)  endend RC.zigzag(5)
Output:
 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


## 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}. 
Output:
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]]


## 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 FOREND PROGRAM
Output:
 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

## Euphoria

Translation of: C#
function zigzag(integer size)    sequence s    integer i, j, d, max    s = repeat(repeat(0,size),size)    i = 1  j = 1  d = -1    max = size*size    for n = 1 to floor(max/2)+1 do        s[i][j] = n        s[size-i+1][size-j+1] = max-n+1        i += d  j-= d        if i < 1 then            i += 1  d = -d        elsif j < 1 then            j += 1  d = -d        end if    end for    return send function ? zigzag(5)
Output:
{
{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}
}


## F#

 //Produce a zig zag matrix - Nigel Galloway: April 7th., 2015let 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) 
Output:
zz 5 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]]

zz 8 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]]


Let's try something a little less square man

zz 5 8
[[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]]


## Fan

using gfx  // for Point; convenient x/y wrapper **** A couple methods for generating a 'zigzag' array like****   0  1  5  6**   2  4  7 12**   3  8 11 13**   9 10 14 15**class ZigZag{  ** return an n x n array of uninitialized Int  static Int[][] makeSquareArray(Int n)  {    Int[][] grid := Int[][,] {it.size=n}    n.times |i| { grid[i] = Int[,] {it.size=n} }    return grid  }    Int[][] zig(Int n)  {    grid := makeSquareArray(n)     move := |Int i, Int j->Point|    { return j < n - 1 ? Point(i <= 0 ? 0 : i-1, j+1) : Point(i+1, j) }    pt := Point(0,0)    (n*n).times |i| {      grid[pt.y][pt.x] = i      if ((pt.x+pt.y)%2 != 0) pt = move(pt.x,pt.y)      else {tmp:= move(pt.y,pt.x); pt = Point(tmp.y, tmp.x) }    }    return grid  }   public static Int[][] zag(Int size)  {    data := makeSquareArray(size)     Int i := 1    Int j := 1    for (element:=0; element < size * size; element++)    {      data[i - 1][j - 1] = element      if((i + j) % 2 == 0) {        // Even stripes        if (j < size) {          j++        } else {          i += 2        }        if (i > 1) {          i--        }      } else {        // Odd stripes        if (i < size) {          i++;        } else {          j += 2        }        if (j > 1) {          j--        }      }    }    return data;  }   Void print(Int[][] data)  {    data.each |row|    {      buf := StrBuf()      row.each |num|      {        buf.add(num.toStr.justr(3))      }      echo(buf)    }  }   Void main()  {    echo("zig method:")    print(zig(8))    echo("\nzag method:")    print(zag(8))  }}

## Forth

0 value diag : south  diag abs + cell+ ; ' cell+ value zig' south value zag : init ( n -- )  1- cells negate to diag  ['] cell+ to zig  ['] south to zag ; : swap-diag   zig zag to zig to zag ; : put ( n addr -- n+1 addr )  2dup !  swap 1+ swap ; : turn ( addr -- addr+E/S )  zig execute  swap-diag  diag negate to diag ; : zigzag ( matrix n -- )  { n } n init  0 swap  n 1 ?do    put turn    i 0 do put diag + loop  loop  swap-diag  n 1 ?do    put turn    n i 1+ ?do put diag + loop  loop  ! ; : .matrix ( n matrix -- )  over 0 do    cr    over 0 do      dup @ 3 .r cell+    loop  loop 2drop ; : test ( n -- )  here over zigzag here .matrix ; 5 test  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 ok

## Fortran

Works with: Fortran version 90 and later
PROGRAM ZIGZAG   IMPLICIT NONE    INTEGER, PARAMETER :: size = 5    INTEGER :: zzarray(size,size), x(size*size), y(size*size), i, j     ! index arrays    x = (/ ((j, i = 1, size), j = 1, size) /)    y = (/ ((i, i = 1, size), j = 1, size) /)     ! Sort indices    DO i = 2, size*size       j = i - 1       DO WHILE (j>=1 .AND. (x(j)+y(j)) > (x(i)+y(i)))          j = j - 1       END DO       x(j+1:i) = cshift(x(j+1:i),-1)       y(j+1:i) = cshift(y(j+1:i),-1)    END DO     ! Create zig zag array    DO i = 1, size*size       IF (MOD(x(i)+y(i), 2) == 0) THEN          zzarray(x(i),y(i)) = i - 1       ELSE          zzarray(y(i),x(i)) = i - 1       END IF    END DO     ! Print zig zag array    DO j = 1, size       DO i = 1, size          WRITE(*, "(I5)", ADVANCE="NO") zzarray(i,j)       END DO       WRITE(*,*)    END DO  END PROGRAM ZIGZAG

## FreeBASIC

' FB 1.05.0 Win64 Dim As Integer n Do  Input "Enter size of matrix "; nLoop 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-diagonalszigzag(1, 1) = 0If 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         LoopEnd If ' print zigzag matrix if n < 20 PrintIf 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 iElse   Print "Matrix is too big to display on 80 column console"End If PrintPrint "Press any key to quit"Sleep
Output:
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


## GAP

ZigZag := function(n)  local a, i, j, k;  a := NullMat(n, n);  i := 1;  j := 1;  for k in [0 .. n*n - 1] do    a[i][j] := k;    if (i + j) mod 2 = 0 then      if j < n then        j := j + 1;      else        i := i + 2;      fi;      if i > 1 then        i := i - 1;      fi;    else      if i < n then        i := i + 1;      else        j := j + 2;      fi;      if j > 1 then        j := j - 1;      fi;    fi;  od;  return a;end; PrintArray(ZigZag(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 ] ]

## Go

Translation of: Groovy
Edge direct algorithm
package main import (    "fmt"    "strconv") func zz(n int) []int {    r := make([]int, n*n)    i := 0    n2 := n * 2    for d := 1; d <= n2; d++ {        x := d - n        if x < 0 {            x = 0        }        y := d - 1        if y > n-1 {            y = n - 1        }        j := n2 - d        if j > d {            j = d        }        for k := 0; k < j; k++ {            if d&1 == 0 {                r[(x+k)*n+y-k] = i            } else {                r[(y-k)*n+x+k] = i            }            i++        }    }     return r} func main() {    const n = 5    w := len(strconv.Itoa(n*n - 1))    for i, e := range zz(n) {        fmt.Printf("%*d ", w, e)        if i%n == n-1 {            fmt.Println("")        }    }}
Output:
 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


## Groovy

### Edge

An odd technique that traverses the grid edges directly and calculates the transform onto the grid.

def zz = { n ->  grid = new int[n][n]  i = 0  for (d in 1..n*2) {    (x, y) = [Math.max(0, d - n), Math.min(n - 1, d - 1)]     Math.min(d, n*2 - d).times {       grid[d%2?y-it:x+it][d%2?x+it:y-it] = i++;      }  }  grid}
Output:
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


### Sorting

Ported from the Python example with some input from J

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 } }}
Output:
 > zz(5).each { it.each { print("${it}".padLeft(3)) }; 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  ## Haskell Computing the array: import Data.Array (array, bounds, range, (!))import Data.Monoid (mappend)import Data.List (sortBy) compZig (x,y) (x',y') = compare (x+y) (x'+y') mappend if even (x+y) then compare x x' else compare y y' zigZag upper = array b$ zip (sortBy compZig (range b))                             [0..]  where b = ((0,0),upper)

compZig compares coordinates using the order of a zigzag walk: primarily, the antidiagonals; secondarily, alternating directions along them.

In zigZag, array takes the bounds and a list of indexes paired with values. We take the list of all indexes, range b, 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):

import Text.Printf (printf) -- format a 2d array of integers neatlyshow2d 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)]

Or, building a list of lists with mapAccumL:

import Data.List (mapAccumL)import Data.Text (justifyRight, pack, unpack) zigZag :: Int -> [[Int]]zigZag n = horizontals n (diagonals n)  where     diagonals :: Int -> [[Int]]    diagonals n =      snd $mapAccumL (\xs h -> let (grp, rst) = splitAt h xs in ( rst , (if mod h 2 /= 0 then reverse else id) grp)) [0 .. (n * n) - 1] (slope ++ [n] ++ reverse slope) where slope = [1 .. n - 1] horizontals :: Int -> [[Int]] -> [[Int]] horizontals n xss = if not (null xss) then let (edge, rst) = splitAt n xss in (head <$> edge) :                horizontals n (dropWhile null (tail <$> edge) ++ rst) else [] main :: IO ()main = putStrLn$  unlines $(concat . (unpack <$>)) . ((justifyRight 3 ' ' . pack . show) <$>) <$>  zigZag 5
Output:
  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

## Icon and Unicon

This solution works for both Icon and Unicon.

procedure main(args)   n := integer(!args) | 5   every !(A := list(n)) := list(n)   A := zigzag(A)   show(A)end procedure show(A)    every writes(right(!A,5) | "\n")end procedure zigzag(A)    x := [0,0]    every i := 0 to (*A^2 -1) do {        x := nextIndices(*A, x)        A[x[1]][x[2]] := i        }       return Aend procedure nextIndices(n, x)    return if (x[1]+x[2])%2 = 0           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
Output:
->zz
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
->


## IS-BASIC

100 PROGRAM "ZigZag.bas"110 LET SIZE=5120 NUMERIC A(1 TO SIZE,1 TO SIZE)130 LET I,J=1140 FOR E=0 TO SIZE^2-1150   LET A(I,J)=E160   IF ((I+J) BAND 1)=0 THEN170     IF J<SIZE THEN180       LET J=J+1190     ELSE200       LET I=I+2210     END IF220     IF I>1 THEN LET I=I-1230   ELSE240     IF I<SIZE THEN250       LET I=I+1260     ELSE270       LET J=J+2280     END IF290     IF J>1 THEN LET J=J-1300   END IF310 NEXT320 FOR ROW=1 TO SIZE330   FOR COL=1 TO SIZE340     PRINT USING " ##":A(ROW,COL);350   NEXT360   PRINT370 NEXT

## J

A succinct way:

   ($[: /:@; <@|.</[email protected])@,~ 5 0 1 5 6 14 2 4 7 13 15 3 8 12 16 21 9 11 17 20 2210 18 19 23 24 This version is longer, but more "mathematical" and less "procedural":  ($ [: /:@; [: <@(A.~_2|#)/. i.)@,~ 5 0  1  5  6 14 2  4  7 13 15 3  8 12 16 21 9 11 17 20 2210 18 19 23 24

Leveraging a useful relationship among the indices:

   ($([: /:@;@(+/"1 <@|.</. ]) (#: [email protected](*/))))@,~ 5 0 1 5 6 14 2 4 7 13 15 3 8 12 16 21 9 11 17 20 2210 18 19 23 24 By the way, all the edge cases are handled transparently, without any special checks. Furthermore, by simply removing the trailing @,~ from the solutions, they automatically generalize to rectangular (non-square) matrices:  ($ [: /:@; [: <@|.</. i.) 5 30  1  52  4  63  7 118 10 129 13 14

## Java

public static int[][] Zig_Zag(final int size){ int[][] data = new int[size][size]; int i = 1; int j = 1; for (int element = 0; element < size * size; element++) {  data[i - 1][j - 1] = element;  if ((i + j) % 2 == 0)  {   // Even stripes   if (j < size)    j++;   else    i+= 2;   if (i > 1)    i--;  }  else  {   // Odd stripes   if (i < size)    i++;   else    j+= 2;   if (j > 1)    j--;  } } return data;}

## JavaScript

### Imperative

Works with: SpiderMonkey
for the print() function.
Translation of: Java

Subclasses the Matrix class defined at Matrix Transpose#JavaScript

function ZigZagMatrix(n) {    this.height = n;    this.width = n;     this.mtx = [];    for (var i = 0; i < n; i++)         this.mtx[i] = [];     var i=1, j=1;    for (var e = 0; e < n*n; e++) {        this.mtx[i-1][j-1] = e;        if ((i + j) % 2 == 0) {            // Even stripes            if (j < n) j ++;            else       i += 2;            if (i > 1) i --;        } else {            // Odd stripes            if (i < n) i ++;            else       j += 2;            if (j > 1) j --;        }    }}ZigZagMatrix.prototype = Matrix.prototype; var z = new ZigZagMatrix(5);print(z);print(); z = new ZigZagMatrix(4);print(z);
Output:
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
2,4,7,12
3,8,11,13
9,10,14,15

### Functional

#### ES5

(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);
Output:
[[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]]

#### ES6

(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);
Output:
[[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]]

## Joy

 (*    From the library.*)DEFINE reverse == [] swap shunt;       shunt   == [swons] step. (*    Split according to the parameter given.*)DEFINE take-drop  == [dup] swap dup [[] cons [take swap] concat concat] dip []                     cons concat [drop] concat. (*    Take the first of a list of lists.*)DEFINE take-first == [] cons 3 [dup] times [dup] swap concat [take [first] map                     swap dup] concat swap concat [drop swap] concat swap                     concat [take [rest] step []] concat swap concat [[cons]                     times swap concat 1 drop] concat. DEFINE zigzag == (*    Use take-drop to generate a list of lists.*)4 [dup] times 1 swap from-to-list swap pred 1 swap from-to-list reverse concatswap dup * pred 0 swap from-to-list swap [take-drop i] step [pop list] [cons]while (*    The odd numbers must be modified with reverse.*)[dup size 2 div popd [1 =] [pop reverse] [pop] ifte] map (*    Take the first of the first of n lists.*)swap dup take-first [i] cons times pop (*    Merge the n separate lists.*)[] [pop list] [cons] while (*    And print them.*)swap dup * pred 'd 1 1 format size succ [] cons 'd swons [1 format putchars]concat [step '\n putch] cons step. 11 zigzag.

## jq

Infrastructure:

# 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 spacesdef 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" ) ;  Create a zigzag matrix by zigzagging: 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]) ; # Examplezigzag(5) | neatly(4) Output: $ 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


### another solution

#!/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
Output:

## Modula-3

MODULE ZigZag EXPORTS Main; IMPORT IO, Fmt; TYPE Matrix = REF ARRAY OF ARRAY OF CARDINAL; PROCEDURE Create(size: CARDINAL): Matrix =  PROCEDURE move(VAR i, j: INTEGER) =    BEGIN      IF j < (size - 1) THEN        IF (i - 1) < 0 THEN          i := 0;        ELSE          i := i - 1;        END;        INC(j);      ELSE        INC(i);      END;    END move;   VAR data := NEW(Matrix, size, size);      x, y: INTEGER := 0;  BEGIN    FOR v := 0 TO size * size - 1 DO      data[y, x] := v;      IF (x + y) MOD 2 = 0 THEN        move(y, x);      ELSE        move(x, y);      END;    END;    RETURN data;  END Create; PROCEDURE Print(data: Matrix) =  BEGIN    FOR i := FIRST(data^) TO LAST(data^) DO      FOR j := FIRST(data[0]) TO LAST(data[0]) DO        IO.Put(Fmt.F("%3s", Fmt.Int(data[i, j])));      END;      IO.Put("\n");    END;  END Print; BEGIN  Print(Create(5));END ZigZag.
Output:
  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


## NetRexx

Translation of: REXX
/* NetRexx */options replace format comments java crossref savelog symbols binary zigzag(5) return method zigzag(msize) public static   row = 1  col = 1   ziggy = Rexx(0)  loop j_ = 0 for msize * msize    ziggy[row, col] = j_    if (row + col) // 2 == 0 then do      if col < msize then -        col = col + 1      else row = row + 2      if row \== 1 then -        row = row - 1      end    else do      if row < msize then -        row = row + 1      else col = col + 2      if col \== 1 then -        col = col - 1      end    end j_   L = (msize * msize - 1).length             /*for a constant element width.  */  loop row = 1 for msize                     /*show all the matrix's rows.    */    rowOut = ''    loop col = 1 for msize      rowOut = rowOut ziggy[row, col].right(L)      end col    say rowOut    end row   return

## Nim

Translation of: Python
import algorithm, strutils type Pos = tuple[x, y: int] template newSeqWith(len: int, init: expr): expr =  var result {.gensym.} = newSeq[type(init)](len)  for i in 0 .. <len:    result[i] = init  result proc (m: seq[seq[int]]): string = result = "" for r in m: for c in r: result.add align(c, 2) & " "    result.add "\n" proc zigzagMatrix(n): auto =  result = newSeqWith(n, newSeq[int](n))   var indices = newSeq[Pos]()   for x in 0 .. <n:    for y in 0 .. <n:      indices.add((x,y))   sort(indices, proc(a, b: Pos): int =    result = a.x + a.y - b.x - b.y    if result == 0: result =      (if (a.x + a.y) mod 2 == 0: a.y else: -a.y) -      (if (b.x + b.y) mod 2 == 0: b.y else: -b.y))   for i, p in indices:    result[p.x][p.y] = i echo zigzagMatrix(6)
Output:
 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

## Objeck

Translation of: Java
 function : native : ZigZag(size : Int) ~ Int[,] {  data := Int->New[size, size];  i := 1;  j := 1;   max := size * size;  for(element := 0; element < max ; element += 1;) {    data[i - 1, j - 1] := element;     if((i + j) % 2 = 0) {      # even stripes      if(j < size){        j += 1;      }      else{        i+= 2;      };       if(i > 1) {        i -= 1;      };    }    else{      # ddd stripes      if(i < size){        i += 1;      }      else{        j+= 2;      };       if(j > 1){        j -= 1;      };    };  };   return data;}

## OCaml

Translation of: Common Lisp
let zigzag n =  (* move takes references and modifies them directly *)  let move i j =    if !j < n - 1 then begin      i := max 0 (!i - 1);      incr j    end else      incr i  in  let a = Array.make_matrix n n 0  and x = ref 0 and y = ref 0 in  for v = 0 to n * n - 1 do    a.(!x).(!y) <- v;    if (!x + !y) mod 2 = 0 then      move x y    else      move y x  done;  a

## Octave

Translation of: Stata
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;  endforendfunction 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);  endforendfunction >> 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

Alternate solution, filling pairs of diagonals.

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;  endforendfunction >> 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

## ooRexx

Translation of: Java
 call printArray zigzag(3)saycall printArray zigzag(4)saycall 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
Output:
|  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 |


## Oz

Implemented as a state machine:

declare  %%            state          move   success     failure  States = unit(right:        [ 1# 0  downLeft    downInstead]                downInstead:  [ 0# 1  downLeft    terminate]                downLeft:     [~1# 1  downLeft    down]                down:         [ 0# 1  topRight    rightInstead]                rightInstead: [ 1# 0  topRight    terminate]                topRight:     [ 1#~1  topRight    right])   fun {CreateZigZag N}     ZZ = {Create2DTuple N N}      %% recursively walk through 2D tuple and set values     proc {Walk Pos=X#Y Count State}        [Dir Success Failure] = States.State        NextPos = {Record.zip Pos Dir Number.'+'}        Valid = {Record.all NextPos fun {$C} C > 0 andthen C =< N end} NewPos = if Valid then NextPos else Pos end NewCount = if Valid then Count + 1 else Count end NewState = if Valid then Success else Failure end in ZZ.Y.X = Count if NewState \= terminate then {Walk NewPos NewCount NewState} end end in {Walk 1#1 0 right} ZZ end fun {Create2DTuple W H} T = {MakeTuple unit H} in {Record.forAll T fun {$} {MakeTuple unit W} end}     T  endin  {Inspect {CreateZigZag 5}}

## PARI/GP

Translation of: C.23
zz(n)={	my(M=matrix(n,n),i,j,d=-1,start,end=n^2-1);	while(ct--,		M[i+1,j+1]=start;		M[n-i,n-j]=end;		start++;		end--;		i+=d;		j-=d;		if(i<0,			i++;			d=-d		,			if(j<0,				j++;				d=-d			)		);		if(start>end,return(M))	)};

## Pascal

Program zigzag( input, output ); const  size = 5;var  zzarray: array [1..size, 1..size] of integer;  element, i, j: integer;  direction: integer;  width, n: integer; begin  i := 1;  j := 1;  direction := 1;  for element := 0 to (size*size) - 1 do  begin    zzarray[i,j] := element;    i := i + direction;    j := j - direction;    if (i = 0) then      begin        direction := -direction;        i := 1;        if (j > size) then        begin          j := size;          i := 2;        end;      end    else if (i > size) then      begin        direction := -direction;        i := size;        j := j + 2;      end    else if (j = 0) then      begin        direction := -direction;        j := 1;        if (i > size) then        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]:width);    writeln;  end;end.
Output:
  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

Output:
with size set to 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


Translation of: Seed7

## Phix

Translation of: C#
integer n = 9integer zstart = 0, zend = n*n-1--integer zstart = 1, zend = n*nstring fmt = sprintf("%%%dd",length(sprintf("%d",zend)))sequence m = repeat(repeat("??",n),n)integer x = 1, y = 1, d = -1while 1 do    m[x][y] = sprintf(fmt,zstart)    if zstart=zend then exit end if    zstart += 1    m[n-x+1][n-y+1] = sprintf(fmt,zend)    zend -= 1    x += d    y -= d    if x<1 then        x += 1        d = -d    elsif y<1 then        y += 1        d = -d    end ifend while for i=1 to n do    m[i] = join(m[i])end forputs(1,join(m,"\n"))

Alternative:

integer n = 5string fmt = sprintf("%%%dd",length(sprintf("%d",n*n-1)))sequence m = repeat(repeat("??",n),n)integer x = 1, y = 1for d=0 to n*n-1 do    m[y][x] = sprintf(fmt,d)    if mod(x+y,2) then        {x,y} = iff(y<n?{x-(x>1),y+1}:{x+1,y})    else        {x,y} = iff(x<n?{x+1,y-(y>1)}:{x,y+1})    end ifend for for i=1 to n do    m[i] = join(m[i])end forputs(1,join(m,"\n"))

## PHP

function ZigZagMatrix($num) {$matrix = array();    for ($i = 0;$i < $num;$i++){		$matrix[$i] = array();	}     $i=1;$j=1;    for ($e = 0;$e < $num*$num; $e++) {$matrix[$i-1][$j-1] = $e; if (($i + $j) % 2 == 0) { if ($j < $num){$j++;			}else{				$i += 2; } if ($i > 1){ 				$i --; } } else { if ($i < $num){$i++;			}else{				$j += 2; } if ($j > 1){				$j --; } } } return$matrix;}

## PicoLisp

This example uses 'grid' from "lib/simul.l", which maintains a two-dimensional structure and is normally used for simulations and board games.

(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) )
Output:
  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

## 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.            *//* Written 22 February 2010.                             */    declare n fixed binary;    put skip list ('Please type the size of the matrix:');   get list (n); begin;   declare A(n,n) fixed binary;   declare (i, j, inc, q) fixed binary;    on subrg snap begin;      declare i fixed binary;      do  i = 1 to n;         put skip edit (a(i,*)) (f(4));      end;      stop;   end;    A = -1;   inc = -1;   i, j = 1; loop:   do q = 0 to n**2-1;      a(i,j) = q;      if q = n**2-1 then leave;      if i = 1 & j = n then         if iand(j,1) = 1 then /* odd-sided matrix */            do; i = i + 1; inc = -inc; iterate loop; end;         else  /* an even-sided matrix */            do; i = i + inc; j = j - inc; iterate loop; end;      if inc = -1 then if i+inc < 1 then         do; inc = -inc; j = j + 1; a(i,j) = q; iterate loop; end;      if inc = 1 then if i+inc > n then         do; inc = -inc; j = j + 1; a(i,j) = q; iterate loop; end;      if inc = 1 then if j-inc < 1 then         do; inc = -inc; i = i + 1; a(i,j) = q; iterate loop; end;      if inc = -1 then if j - inc > n then         do; inc = -inc; i = i + 1; a(i,j) = q; iterate loop; end;      i = i + inc; j = j - inc;   end;    /* Display the square. */   do  i = 1 to n;      put skip edit (a(i,*)) (f(4));   end;end;
Output:
   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 

## Plain TeX

The code works with any etex engine.

\long\def\antefi#1#2\fi{#2\fi#1}\def\fornum#1=#2to#3(#4){%	\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

pdf output:

 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

## PostScript

This implementation is far from being elegant or smart, but it builds the zigzag how a human being could do, and also draws lines to show the path.

%!PS%%BoundingBox: 0 0 300 200/size 9 def % defines row * column (9*9 -> 81 numbers,            % from 0 to 80)/itoa { 2 string cvs } bind def% visual bounding box...% 0 0 moveto 300 0 lineto 300 200 lineto 0 200 lineto% closepath stroke20 150 translate% it can be easily enhanced to support more columns and% rows. This limit is put here just to avoid more than 2% digits, mainly because of formattingsize size mul 99 le {   /Helvetica findfont 14 scalefont setfont   /ulimit size size mul def   /sizem1 size 1 sub def   % prepare the number list   0 ulimit 1 sub { dup 1 add } repeat   ulimit array astore   /di -1 def /dj 1 def   /ri 1 def /rj 0 def /pus true def   0 0 moveto   /i 0 def /j 0 def   {  % can be rewritten a lot better :)      0.8 setgray i 30 mul j 15 mul neg lineto stroke      0 setgray i 30 mul j 15 mul neg moveto itoa show      i 30 mul j 15 mul neg moveto      pus {         i ri add size ge {             /ri 0 def /rj 1 def         } if         j rj add size ge {             /ri 1 def /rj 0 def         } if         /pus false def         /i i ri add def         /j j rj add def         /ri rj /rj ri def def      } {          i di add dup    0 le                  exch sizem1 ge or          j dj add dup    0 le                  exch sizem1 ge or             or {                /pus true def                /i i di add def /j j dj add def                /di di neg def /dj dj neg def          } {                /i i di add def /j j dj add def          } ifelse      } ifelse   } forall   stroke showpage} if%%EOF

## PowerShell

function zigzag( [int] $n ) {$zigzag=New-Object 'Object[,]' $n,$n    $nodd =$n -band 1    $nm1 =$n - 1    $i=0;$j=0;    foreach( $k in 0..($n * $n - 1 ) ) {$zigzag[$i,$j] = $k$iodd = $i -band 1$jodd = $j -band 1 if( ($j -eq $nm1 ) -and ($iodd -ne $nodd ) ) {$i++        } elseif( ( $i -eq$nm1 ) -and ( $jodd -eq$nodd ) ) {            $j++ } elseif( ($i -eq 0 ) -and ( -not $jodd ) ) {$j++        } elseif( ( $j -eq 0 ) -and$iodd ) {            $i++ } elseif($iodd -eq $jodd ) {$i--            $j++ } else {$i++            $j-- } } ,$zigzag} function displayZigZag( [int] $n ) {$a = zigzag $n 0..$n | ForEach-Object {        $b=$_        $pad=($n*$n-1).ToString().Length "$(0..$n | ForEach-Object { "{0,$pad}" -f $a[$b,$_] } )" }} ### An Alternate Display Display the zig-zag matrix using the Format-Wide cmdlet:  zigzag 5 | Format-Wide {"{0,2}" -f$_} -Column 5 -Force
Output:
 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


## Prolog

Works with: SWi-Prolog
zig_zag(N) :-	zig_zag(N, N). % compute zig_zag for a matrix of Lig lines of Col columnszig_zag(Lig, Col) :-	length(M, Lig),	maplist(init(Col), M),	fill(M, 0, 0, 0, Lig, Col, up),	% display the matrix	maplist(print_line, M).  fill(M, Cur, L, C, NL, NC, _) :-	L is NL - 1,	C is NC - 1,	nth0(L, M, Line),	nth0(C, Line, Cur). fill(M, Cur, L, C, NL, NC, Sens) :-	nth0(L, M, Line),	nth0(C, Line, Cur),	Cur1 is Cur + 1,	compute_next(NL, NC, L, C, Sens, L1, C1, Sens1),	fill(M, Cur1, L1, C1, NL, NC, Sens1).  init(N, L) :-	length(L, N). % compute_next% arg1 : Number of lnes of the matrix% arg2 : number of columns of the matrix% arg3 : current line% arg4 : current column% arg5 : current direction of movement% arg6 : nect line% arg7 : next column% arg8 : next direction of movementcompute_next(_NL, NC, 0, Col, up, 0, Col1, down) :-	Col < NC - 1,	Col1 is Col+1. compute_next(_NL, NC, 0, Col, up, 1, Col, down) :-	Col is NC - 1. compute_next(NL, _NC, Lig, 0, down, Lig1, 0, up) :-	Lig < NL - 1,	Lig1 is Lig+1. compute_next(NL, _NC, Lig, 0, down, Lig, 1, up) :-	Lig is NL - 1. compute_next(NL, _NC, Lig, Col, down, Lig1, Col1, down) :-	Lig < NL - 1,	Lig1 is Lig + 1,	Col1 is Col-1. compute_next(NL, _NC, Lig, Col, down, Lig, Col1, up) :-	Lig is NL - 1,	Col1 is Col+1. compute_next(_NL, NC, Lig, Col, up, Lig1, Col1, up) :-	Col < NC - 1,	Lig1 is Lig - 1,	Col1 is Col+1. compute_next(_NL, NC, Lig, Col, up, Lig1, Col, down) :-	Col is NC - 1,	Lig1 is Lig + 1.  print_line(L) :-	maplist(print_val, L),	nl. print_val(V) :-	writef('%3r ', [V]).
Output:
?- zig_zag(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
true .

?- zig_zag(5, 7).
0   1   5   6  14  15  24
2   4   7  13  16  23  25
3   8  12  17  22  26  31
9  11  18  21  27  30  32
10  19  20  28  29  33  34
true .

?- zig_zag(7,5).
0   1   5   6  14
2   4   7  13  15
3   8  12  16  24
9  11  17  23  25
10  18  22  26  31
19  21  27  30  32
20  28  29  33  34
true .


## PureBasic

Translation of: AutoHotkey

Procedure zigZag(size)  Protected i, v, x, y   Dim a(size - 1, size - 1)   x = 1  y = 1  For i = 1 To  size * size  ;loop once for each element    a(x - 1, y - 1) = v      ;assign the next index     If (x + y) & 1 = 0       ;even diagonal (zero based count)      If x < size            ;while inside the square        If y > 1             ;move right-up          y - 1        EndIf         x + 1      Else        y + 1                ;on the edge increment y, but not x until diagonal is odd      EndIf     Else                     ;odd diagonal (zero based count)      If y < size            ;while inside the square        If x > 1             ;move left-down          x - 1        EndIf          y + 1      Else        x + 1                ;on the edge increment x, but not y until diagonal is even      EndIf     EndIf     v + 1  Next     ;generate and show printout  PrintN("Zig-zag matrix of size " + Str(size) + #CRLF$) maxDigitCount = Len(Str(size * size)) + 1 For y = 0 To size - 1 For x = 0 To size - 1 Print(RSet(Str(a(x, y)), maxDigitCount, " ")) Next PrintN("") Next PrintN("")EndProcedure If OpenConsole() zigZag(5) zigZag(6) Print(#CRLF$ + #CRLF+ "Press ENTER to exit") Input() CloseConsole()EndIf Output: Zig-zag matrix of 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 Zig-zag matrix of 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  ## Python ### Python: By sorting indices There is a full explanation of the algorithm used by paddy3118. def zigzag(n): indexorder = sorted(((x,y) for x in range(n) for y in range(n)), key = lambda (x,y): (x+y, -y if (x+y) % 2 else y) ) return {index: n for n,index in enumerate(indexorder)} def printzz(myarray): n = int(len(myarray)** 0.5 +0.5) for x in range(n): for y in range(n): print "%2i" % myarray[(x,y)], print printzz(zigzag(6)) Output:  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 ### Alternative version, Translation of: Common Lisp def zigzag(n): def move(i, j): if j < (n - 1): return max(0, i-1), j+1 else: return i+1, j a = [[0] * n for _ in xrange(n)] x, y = 0, 0 for v in xrange(n * n): a[y][x] = v if (x + y) & 1: x, y = move(x, y) else: y, x = move(y, x) return a from pprint import pprintpprint(zigzag(5)) Output: [[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]] ### Alternative version, inspired by the Common Lisp Alternative Approach  COLS = 9def CX(x, ran): while True: x += 2 * next(ran) yield x x += 1 yield xran = []d = -1for 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 *= -1for x in range(0,COLS): for y in range(x, x+COLS): print(repr(next(ran[y])).rjust(3), end = ' ') print()  Output: COLS = 5 Produces:  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  Output: COLS = 8 Produces:  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  Output: COLS = 9 Produces:  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  ### Another alternative version  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)  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  ## Rascal  This example is incorrect. Please fix the code and remove this message.Details: 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 Python example. As explained on the Talk page, the key way to understand a zig-zag matrix is to write down an example with coordinates: 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) If you order these coordinates on the number, you create the order:  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) 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: 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();}} Output: 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 ## Qi This is a purely functional, very inefficient, and straight forward solution. The code can probably be simplified somewhat.  (define odd? A -> (= 1 (MOD A 2)))(define even? A -> (= 0 (MOD A 2))) (define zigzag-val 0 0 N -> 0 X 0 N -> (1+ (zigzag-val (1- X) 0 N)) where (odd? X) X 0 N -> (1+ (zigzag-val (1- X) 1 N)) 0 Y N -> (1+ (zigzag-val 1 (1- Y) N)) where (odd? Y) 0 Y N -> (1+ (zigzag-val 0 (1- Y) N)) X Y N -> (1+ (zigzag-val (MAX 0 (1- X)) (MIN (1- N) (1+ Y)) N)) where (even? (+ X Y)) X Y N -> (1+ (zigzag-val (MIN (1- N) (1+ X)) (MAX 0 (1- Y)) N))) (define range E E -> [] S E -> [S|(range (1+ S) E)]) (define zigzag N -> (map (/. Y (map (/. X (zigzag-val X Y N)) (range 0 N))) (range 0 N)))  ## R Translation of: Java zigzag <- function(size){ digits <- seq_len(size^2) - 1 mat <- matrix(0, nrow = size, ncol=size) i <- 1 j <- 1 for(element in digits) { mat[i,j] <- element if((i + j) %% 2 == 0) { # 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} zigzag(5) ## 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)  Output:  '((0 2 3 9) (1 4 8 10) (5 7 11 14) (6 12 13 15))  ## REXX This REXX version allows the optional specification of the start and increment values. /*REXX program produces and displays a zig─zag matrix (a square array). */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 /*start with the 1st row, 1st column.*/size=n**2 /*the size of array. */ 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.*/ w=max(length(start), length(start + size*inc) ) /*maximum width of any matrix element. */ do r=1 for n ; _= right(@.r.1, w) /*show all the rows of the matrix. */ do c=2 for n-1; _=_ right(@.r.c, w) /*build a line for the output for a row*/ end /*c*/ /* [↑] matrix elements are aligned. */ say _ /*show the matrix row just constructed.*/ end /*r*/ /*stick a fork in it, we're all done. */ output when using the default input 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  ## Ring  # Project Zig-zag matrix load "guilib.ring"load "stdlib.ring"new qapp { win1 = new qwidget() { setwindowtitle("Zig-zag matrix") setgeometry(100,100,600,400) n = 5 a = newlist(n,n) zigzag = newlist(n,n) 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() }  Output: ## Ruby Translation of: Python def zigzag(n) (seq=*0...n).product(seq) .sort_by {|x,y| [x+y, (x+y).even? ? y : -y]} .each_with_index.sort.map(&:last).each_slice(n).to_aend def print_matrix(m) format = "%#{m.flatten.max.to_s.size}d " * m[0].size puts m.map {|row| format % row}end print_matrix zigzag(5) Output:  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  ## Scala Uses the array indices sort solution used by others here.  def zigzag(n: Int): Array[Array[Int]] = { val l = for (i <- 0 until n*n) yield (i%n, i/n) val lSorted = l.sortWith { case ((x,y), (u,v)) => if (x+y == u+v) if ((x+y) % 2 == 0) x<u else y<v else x+y < u+v } val res = Array.ofDim[Int](n, n) lSorted.zipWithIndex foreach { case ((x,y), i) => res(y)(x) = i } res } zigzag(5).foreach{ ar => ar.foreach(x => print("%3d".format(x))) println } Output:  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  ## Scilab Translation of: Octave function a = zigzag3(n) a = zeros(n, n) for k=1: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 endendfunction -->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. ## Seed7  include "seed7_05.s7i"; const type: matrix is array array integer; const func matrix: zigzag (in integer: size) is func  result    var matrix: s is matrix.value;  local    var integer: i is 1;    var integer: j is 1;    var integer: d is -1;    var integer: max is 0;    var integer: n is 0;  begin    s := size times size times 0;    max := size ** 2;    for n range 1 to max div 2 + 1 do      s[i][j] := n;      s[size - i + 1][size - j + 1] := max - n + 1;      i +:= d;      j -:= d;      if i < 1 then        incr(i);        d := -d;      elsif j < 1 then        incr(j);        d := -d;      end if;    end for;  end func; const proc: main is func  local    var matrix: s is matrix.value;    var integer: i is 0;    var integer: num is 0;  begin    s := zigzag(7);    for i range 1 to length(s) do      for num range s[i] do        write(num lpad 4);      end for;      writeln;    end for;  end func;
Output:
   1   2   6   7  15  16  28
3   5   8  14  17  27  29
4   9  13  18  26  30  39
10  12  19  25  31  38  40
11  20  24  32  37  41  46
21  23  33  36  42  45  47
22  34  35  43  44  48  49


## Sidef

Translation of: Perl
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}) }
Output:
   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


## 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:

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  |    +--------------------------+

Now the corrected matrix, which solves the task:

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  |    +--------------------------+

The correction is given by the difference:

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  |    +--------------------------+

## Tcl

Using print_matrix from Matrix Transpose

proc zigzag {size} {    set m [lrepeat $size [lrepeat$size .]]    set x 0; set dx -1    set y 0; set dy 1     for {set i 0} {$i <$size ** 2} {incr i} {        if {$x >=$size} {            incr x -1            incr y 2            negate dx dy        } elseif {$y >=$size} {            incr x 2            incr y -1            negate dx dy        } elseif {$x < 0 &&$y >= 0} {            incr x            negate dx dy        } elseif {$x >= 0 &&$y < 0} {            incr y            negate dx dy        }        lset m $x$y $i incr x$dx        incr y $dy } return$m} proc negate {args} {    foreach varname $args { upvar 1$varname var        set var [expr {-1 * \$var}]    }} print_matrix [zigzag 5]
Output:
 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

## uBasic/4tH

Translation of: BBC BASIC
S = 5 i = 1j = 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  EndIfNext For r = 0 To S-1  For c = 0 To S-1    Print Using "___#";@(r * S + c);  Next  PrintNext
Output:
   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

## Ursala

#import std#import nat zigzag = ~&mlPK2xnSS+ num+ ==+sum~~|[email protected]+ iota

test program (three examples):

#cast %nLLL tests = zigzag* <4,5,6>
Output:
<
<
<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>>,
<
<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>>>

## VBA

 Public Sub zigzag(n)Dim a() As Integer'populate a (1,1) to a(n,n) in zigzag pattern 'check if n too smallIf n < 1 Then  Debug.Print "zigzag: enter a number greater than 1"  Exit SubEnd If 'initializeReDim a(1 To n, 1 To n)i = 1       'i is the rowj = 1       'j is the columnP = 0       'P is the next numbera(i, j) = P 'fill in initial value 'now zigzag through the matrix and fill it inDo While (i <= n) And (j <= n)  'move one position to the right or down the rightmost column, if possible  If j < n Then    j = j + 1  ElseIf i < n Then    i = i + 1  Else    Exit Do  End If  'fill in  P = P + 1: a(i, j) = P  'move down to the left  While (j > 1) And (i < n)    i = i + 1: j = j - 1    P = P + 1: a(i, j) = P  Wend  'move one position down or to the right in the bottom row, if possible  If i < n Then    i = i + 1  ElseIf j < n Then    j = j + 1  Else    Exit Do  End If  P = P + 1: a(i, j) = P  'move back up to the right  While (i > 1) And (j < n)    i = i - 1: j = j + 1    P = P + 1: a(i, j) = P  WendLoop 'print resultDebug.Print "Result for n="; n; ":"For i = 1 To n  For j = 1 To n    Debug.Print a(i, j),  Next  Debug.PrintNextEnd Sub
Output:
zigzag 5
Result for 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

zigzag 6
Result for 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


## VBScript

Translation of: BBC BASIC
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	NextEnd Function
Output:
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


## 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);    ];]
Output:
  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


## Yabasic

Size = 5DIM array(Size-1, Size-1) i = 1j = 1FOR 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  ENDIFNEXT e FOR row = 0 TO Size-1  FOR col = 0 TO Size-1    PRINT array(row,col) USING "##";  NEXT col  PRINTNEXT row

## zkl

Translation of: Groovy
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())});}
Translation of: 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.

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);}

To be pedantic, the same as above, but using the output of the list comprehension:

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);}
Output:
The results are the same:
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