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.

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

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

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:

This isn't the best way to solve this task
and the algorithm is completely unintuitive
without some major exploration of the code.
But! It is pretty fast for n < 10000.

function matrix = zigZag(n)

%This is very unintiutive. This algorithm parameterizes the%zig-zagging movement along the matrix indicies. The easiest way to see%what this algorithm does is to go through line-by-line and write out%what the algorithm does on a peace of paper.

xy =[0for _ inrange(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 inrange(1, HALFWAY + KERNEL_ODD):if direction >0:# going up and rightif iy ==0:# are at top ix +=1 direction = -1else: ix +=1 iy -=1else:# going down and leftif ix ==0:# are at left iy +=1 direction =1else: 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 replacefor i inrange(1, NUMBER_INDEXES):if xy[i]==0 : xy[i]= NUMBER_INDEXES - 1 - xy[NUMBER_INDEXES - 1 - i]

do r=1for n ; _= right(@.r.1, w)/*show all the rows of the matrix. */do c=2for 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. */

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;

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