Talk:Zig-zag matrix: Difference between revisions

more exposition
No edit summary
(more exposition)
Line 252:
And that's why I like J.
 
== further J exposition ==
 
One thing that may not be clear about the J code, and therefore might render it confusing, is that is has no variables. It is completely functional, and the arguments are implicit (the arragement of the expression determines how and where inputs and results are passed).
 
A verbose version of this functional expression might be written:
<pre>
zigZag =: rearrange (antidiagonals integerList)
rearrange =: reshape reorder
reshape =: $
reorder =: grade@flatten
grade =: /:
flatten =: ;
antidiagonals =: sumOfCoords rClass identity
sumOfCoords =: sum@antibase
sum =: +/
antibase =: #:
rClass =: <@maybeRevers classify
maybeRevers =: permute~ evenOrOdd
permute =: A.
evenOrOdd =: _2 mod len
mod =: |
len =: #
classify =: /.
identity =: ] NB. Copy of argument
integerList =: zeroToN_1@product
zeroToN_1 =: i.
product =: */ NB. Note resemblance to sum ('/' is zipWith)
</pre>
 
To explicitly recreate the function calls that occur when the function is invoked (with assignments being what the interpreter actually does, and everything else just to show you what's going on):
<pre>
INPUT =: 3 3
 
PRODUCT =: product INPUT
PRODUCT
9
INTEGERLIST =: zeroToN_1 PRODUCT
INTEGERLIST
0 1 2 3 4 5 6 7 8
 
INPUT <@antibase INTEGERLIST
+---+---+---+---+---+---+---+---+---+
|0 0|0 1|0 2|1 0|1 1|1 2|2 0|2 1|2 2|
+---+---+---+---+---+---+---+---+---+
INPUT sum@antibase INTEGERLIST
0 1 2 1 2 3 2 3 4
SUMOFCOORDS=:INPUT sumOfCoords INTEGERLIST
SUMOFCOORDS
0 1 2 1 2 3 2 3 4
 
SUMOFCOORDS <classify INTEGERLIST NB. Anti-diagonals
+-+---+-----+---+-+
|0|1 3|2 4 6|5 7|8|
+-+---+-----+---+-+
SUMOFCOORDS evenOrOdd classify INTEGERLIST NB. Anti-diagonal lengths alternate, even and odd
_1 0 _1 0 _1
0 permute 1 2 3 NB. 0 permute X is just X
1 2 3
_1 permute 1 2 3 NB. _1 permute X is X reversed
3 2 1
maybeRevers 1 2 3 NB. Odd lengths reversed
3 2 1
maybeRevers 1 2 3 4 NB. Even lengths left alone
1 2 3 4
 
ANTID =: SUMOFCOORDS rClass INTEGERLIST
ANTID NB. Anti-diagonals, appropriately reversed
+-+---+-----+---+-+
|0|1 3|6 4 2|5 7|8|
+-+---+-----+---+-+
 
flatten ANTID NB. Not exciting
0 1 3 6 4 2 5 7 8
grade FLAT_ANTID NB. How to permute, in order to sort
0 1 5 2 4 6 3 7 8
REORDERED=:reorder ANTID
REORDERED
0 1 5 2 4 6 3 7 8
 
INPUT reshape REORDERED NB. Make it a matrix
0 1 5
2 4 6
3 7 8
 
ZIGZAG=:INPUT reshape REORDERED NB. Done
ZIGZAG
0 1 5
2 4 6
3 7 8
</pre>
 
So, to transliterate this to another (inconsistent) pseudo-language:
<pre>
 
function zigZag(int-list INPUT) as matrix
{
return rearrange(INPUT, antidiagonals(INPUT,integerList(INPUT))
}
 
function rearrange(int-list SHAPE, int-list-list ANTIDIAGONALS) as matrix
{
return reshape(SHAPE,reorder(ANTIDIAGONALS))
}
 
function reorder(int-list-list ANTIDIAGONALS) as int-list
{
RESULTS = []
for each ANTIDIAGONAL in ANTIDIAGONALS
{
RESULTS.append(ANTIDIAGONAL) // Flatten the list-list to a list
}
 
return grade(RESULTS)
}
 
function antidiagonals(int-list INPUT, int-list INTEGERS) as int-list-list
{
// Note classify has a function-argument
CLASSES = classify(sumOfCoords(INPUT, INTEGERS), INTEGERS)
RESULTS = []
for each CLASS in CLASSES
{
RESULTS.append(maybeReverse(CLASS))
}
 
return RESULTS
}
 
function sumOfCoords(int-list INPUT, int-list INTEGERS) as int-list
{
COORDINATES = antibase(INPUT, INTEGERS)
RESULTS = []
for each COORDINATE in COORDINATES
{
RESULTS.append(sum(COORDINATE))
}
return RESULTS
}
 
function maybeReverse(int-list LIST) as int-list
{
if ( len(LIST) mod 2 )
{
return reverse(LIST) // FIXME: Fully implement A. (permutation table)
}
else
{
return LIST
}
}
 
function integerList(int-list INPUT) as int-list
{
PROD = product(INPUT)
return [0 .. (PROD-1)]
}
</pre>
Anonymous user