2016 Update

This commit is contained in:
Tina Müller 2016-12-05 22:15:40 +01:00
parent 948b86eafa
commit dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions

View file

@ -1,9 +1,14 @@
;Task:
Produce a zig-zag array.
A zig-zag array is a square arrangement of the first <tt>N<sup>2</sup></tt> integers, where the numbers increase sequentially as you zig-zag along the anti-diagonals of the array. <br>
For a graphical representation, see [[wp:Image:JPEG_ZigZag.svg|JPG zigzag]]
(JPG uses such arrays to encode images).
For example, given <tt>5</tt>, produce this array:
A &nbsp; ''zig-zag'' &nbsp; array is a square arrangement of the first &nbsp; <big>N<sup>2</sup></big> &nbsp; integers, &nbsp; where the
<br>numbers increase sequentially as you zig-zag along the array's &nbsp; [https://en.wiktionary.org/wiki/antidiagonal anti-diagonals].
For a graphical representation, see &nbsp; [[wp:Image:JPEG_ZigZag.svg|JPG zigzag]] &nbsp; (JPG uses such arrays to encode images).
For example, given &nbsp; '''5''', &nbsp; produce this array:
<pre>
0 1 5 6 14
2 4 7 13 15
@ -12,4 +17,13 @@ For example, given <tt>5</tt>, produce this array:
10 18 19 23 24
</pre>
;See also [[Spiral matrix]]
;Related tasks:
* &nbsp; [[Spiral matrix]]
* &nbsp; [[Identity_matrix]]
* &nbsp; [[Ulam_spiral_(for_primes)]]
;See also:
* &nbsp; Wiktionary entry: &nbsp; [https://en.wiktionary.org/wiki/antidiagonal anti-diagonals]
<br><br>

View file

@ -0,0 +1,58 @@
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.

View file

@ -0,0 +1,62 @@
(* ****** ****** *)
//
#include
"share/atspre_define.hats" // defines some names
#include
"share/atspre_staload.hats" // for targeting C
#include
"share/HATS/atspre_staload_libats_ML.hats" // for ...
//
(* ****** ****** *)
//
extern
fun
Zig_zag_matrix(n: int): void
//
(* ****** ****** *)
fun max(a: int, b: int): int =
if a > b then a else b
fun movex(n: int, x: int, y: int): int =
if y < n-1 then max(0, x-1) else x+1
fun movey(n: int, x: int, y: int): int =
if y < n-1 then y+1 else y
fun zigzag(n: int, i: int, row: int, x: int, y: int): void =
if i = n*n then ()
else
let
val () = (if x = row then begin print i; print ','; end else ())
//val () = (begin print x; print ' '; print y; print ' '; print i; print ' '; end)
val nextX: int = if ((x+y) % 2) = 0 then movex(n, x, y) else movey(n, y, x)
val nextY: int = if ((x+y) % 2) = 0 then movey(n, x, y) else movex(n, y, x)
in
zigzag(n, i+1, row, nextX, nextY)
end
implement
Zig_zag_matrix(n) =
let
fun loop(row: int): void =
if row = n then () else
let
val () = zigzag(n, 0, row, 0, 0)
val () = println!(" ")
in
loop(row + 1)
end
in
loop(0)
end
(* ****** ****** *)
implement
main0() = () where
{
val () = Zig_zag_matrix(5)
} (* end of [main0] *)
(* ****** ****** *)

View file

@ -0,0 +1,48 @@
# zig-zag matrix
makeZigZag := proc( n :: number ) :: table is
local move := proc( x :: number, y :: number, upRight :: boolean ) is
if y = n then
upRight := not upRight;
x := x + 1
elif x = 1 then
upRight := not upRight;
y := y + 1
else
x := x - 1;
y := y + 1
fi;
return x, y, upRight
end ;
# create empty table
local result := [];
for i to n do
result[ i ] := [];
for j to n do result[ i, j ] := 0 od
od;
# fill the table
local x, y, upRight := 1, 1, true;
for i to n * n do
result[ x, y ] := i - 1;
if upRight then
x, y, upRight := move( x, y, upRight )
else
y, x, upRight := move( y, x, upRight )
fi
od;
return result
end;
scope
local m := makeZigZag( 5 );
for i to size m do
for j to size m do
printf( " %3d", m[ i, j ] )
od;
print()
od
epocs

View file

@ -1,7 +1,159 @@
"
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
"
-- zigzagMatrix
on zigzagMatrix(n)
-- diagonals :: n -> [[n]]
script diagonals
on lambda(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(range(0, n * n - 1), 1, 1) of mf
end lambda
end script
-- oddReversed :: [a] -> Int -> [a]
script oddReversed
on lambda(lst, i)
if i mod 2 = 0 then
lst
else
reverse of lst
end if
end lambda
end script
rowsFromDiagonals(n, map(oddReversed, lambda(n) of diagonals))
end zigzagMatrix
-- TEST
on run
zigzagMatrix(5)
end run
-- 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 lambda(lst)
length of lst > 1
end lambda
end script
set {edge, residue} to splitAt(n, lst)
{map(my head, edge)} & ¬
rowsFromDiagonals(n, ¬
map(my tail, ¬
filter(lengthOverOne, edge)) & residue)
else
[]
end if
end rowsFromDiagonals
---------------------------------------------------------------------------
-- GENERIC FUNCTIONS
-- 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 lambda(v, i, xs) then set end of lst to v
end repeat
return lst
end tell
end filter
-- 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 lambda(item i of xs, i, xs)
end repeat
return lst
end tell
end map
-- splitAt:: n -> list -> {n items from start of list, rest of list}
-- splitAt :: Int -> [a] -> ([a], [a])
on splitAt(n, xs)
if n > 0 and n < length of xs then
{items 1 thru n of xs, items (n + 1) thru -1 of xs}
else
if n < 1 then
{{}, xs}
else
{xs, {}}
end if
end if
end splitAt
-- head :: [a] -> a
on head(xs)
if length of xs > 0 then
item 1 of xs
else
missing value
end if
end head
-- tail :: [a] -> [a]
on tail(xs)
if length of xs > 1 then
items 2 thru -1 of xs
else
{}
end if
end tail
-- range :: Int -> Int -> [Int]
on range(m, n)
set d to 1
if n < m then set d to -1
set lst to {}
repeat with i from m to n by d
set end of lst to i
end repeat
return lst
end range
-- Lift 2nd class handler function into 1st class script wrapper
-- mReturn :: Handler -> Script
on mReturn(f)
if class of f is script then
f
else
script
property lambda : f
end script
end if
end mReturn

View file

@ -1,13 +1,14 @@
defmodule RC do
require Integer
def zigzag(n) do
indices = for x <- 1..n, y <- 1..n, do: {x,y}
sorted = Enum.sort_by(indices, fn{x,y}->{x+y, if(Integer.is_even(x+y), do: y, else: x)} end)
sorted2 = Enum.sort(Enum.with_index(sorted))
Enum.each(sorted2, fn {{_x,y},i} ->
IO.write "#{i} "
if y==n, do: IO.puts ""
end)
fmt = "~#{to_char_list(n*n-1) |> length}w "
(for x <- 1..n, y <- 1..n, do: {x,y})
|> Enum.sort_by(fn{x,y}->{x+y, if(Integer.is_even(x+y), do: y, else: x)} end)
|> Enum.with_index |> Enum.sort
|> Enum.each(fn {{_x,y},i} ->
:io.format fmt, [i]
if y==n, do: IO.puts ""
end)
end
end

View file

@ -0,0 +1,97 @@
(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);

View file

@ -0,0 +1,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]]

View file

@ -0,0 +1,60 @@
(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);

View file

@ -0,0 +1,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]]

View file

@ -1,59 +1,25 @@
immutable ZigZag
m::Int
n::Int
diag::Array{Int,1}
cmax::Int
numd::Int
lohi::(Int,Int)
end
function zigzag(m::Int, n::Int)
0<m && 0<n || error("The matrix dimensions must be positive.")
ZigZag(m, n, [-1,1], m*n, m+n-1, extrema([m,n]))
end
zigzag(n::Int) = zigzag(n, n)
type ZZState
cnt::Int
cell::Array{Int,1}
dir::Int
dnum::Int
dlen::Int
dcnt::Int
end
Base.length(zz::ZigZag) = zz.cmax
Base.start(zz::ZigZag) = ZZState(1, [1,1], 1, 1, 1, 1)
Base.done(zz::ZigZag, zzs::ZZState) = zzs.cnt > zz.cmax
function Base.next(zz::ZigZag, zzs::ZZState)
s = sub2ind((zz.m, zz.n), zzs.cell[1], zzs.cell[2])
if zzs.dcnt == zzs.dlen
if isodd(zzs.dnum)
if zzs.cell[2] < zz.n
zzs.cell[2] += 1
function zigzag_matrix(n::Int)
matrix = zeros(Int, n, n)
x, y = 1, 1
for i = 0:(n*n-1)
matrix[y,x] = i
if (x + y) % 2 == 0
# Even stripes
if x < n
x += 1
y -= (y > 1)
else
zzs.cell[1] += 1
y += 1
end
else
if zzs.cell[1] < zz.m
zzs.cell[1] += 1
# Odd stripes
if y < n
x -= (x > 1)
y += 1
else
zzs.cell[2] += 1
x += 1
end
end
zzs.dcnt = 1
zzs.dnum += 1
zzs.dir = -zzs.dir
if zzs.dnum <= zz.lohi[1]
zzs.dlen += 1
elseif zz.lohi[2] < zzs.dnum
zzs.dlen -= 1
end
else
zzs.cell += zzs.dir*zz.diag
zzs.dcnt += 1
end
zzs.cnt += 1
return (s, zzs)
return matrix
end

View file

@ -1,24 +1,59 @@
using Formatting
function width{T<:Integer}(n::T)
w = ndigits(n)
n < 0 || return w
return w + 1
immutable ZigZag
m::Int
n::Int
diag::Array{Int,1}
cmax::Int
numd::Int
lohi::(Int,Int)
end
function pretty{T<:Integer}(a::Array{T,2}, indent::Int=4)
lo, hi = extrema(a)
w = max(width(lo), width(hi))
id = " "^indent
fe = FormatExpr(@sprintf(" {:%dd}", w))
s = id
nrow = size(a)[1]
for i in 1:nrow
for j in a[i,:]
s *= format(fe, j)
function zigzag(m::Int, n::Int)
0<m && 0<n || error("The matrix dimensions must be positive.")
ZigZag(m, n, [-1,1], m*n, m+n-1, extrema([m,n]))
end
zigzag(n::Int) = zigzag(n, n)
type ZZState
cnt::Int
cell::Array{Int,1}
dir::Int
dnum::Int
dlen::Int
dcnt::Int
end
Base.length(zz::ZigZag) = zz.cmax
Base.start(zz::ZigZag) = ZZState(1, [1,1], 1, 1, 1, 1)
Base.done(zz::ZigZag, zzs::ZZState) = zzs.cnt > zz.cmax
function Base.next(zz::ZigZag, zzs::ZZState)
s = sub2ind((zz.m, zz.n), zzs.cell[1], zzs.cell[2])
if zzs.dcnt == zzs.dlen
if isodd(zzs.dnum)
if zzs.cell[2] < zz.n
zzs.cell[2] += 1
else
zzs.cell[1] += 1
end
else
if zzs.cell[1] < zz.m
zzs.cell[1] += 1
else
zzs.cell[2] += 1
end
end
i != nrow || continue
s *= "\n"*id
zzs.dcnt = 1
zzs.dnum += 1
zzs.dir = -zzs.dir
if zzs.dnum <= zz.lohi[1]
zzs.dlen += 1
elseif zz.lohi[2] < zzs.dnum
zzs.dlen -= 1
end
else
zzs.cell += zzs.dir*zz.diag
zzs.dcnt += 1
end
return s
zzs.cnt += 1
return (s, zzs)
end

View file

@ -1,26 +1,24 @@
n = 5
println("The n = ", n, " zig-zag matrix:")
a = zeros(Int, (n, n))
for (i, s) in enumerate(zigzag(n))
a[s] = i-1
end
println(pretty(a))
using Formatting
m = 3
println()
println("Generalize to a non-square matrix (", m, "x", n, "):")
a = zeros(Int, (m, n))
for (i, s) in enumerate(zigzag(m, n))
a[s] = i-1
function width{T<:Integer}(n::T)
w = ndigits(n)
n < 0 || return w
return w + 1
end
println(pretty(a))
p = primes(10^3)
n = 7
println()
println("An n = ", n, " prime spiral matrix:")
a = zeros(Int, (n, n))
for (i, s) in enumerate(zigzag(n))
a[s] = p[i]
function pretty{T<:Integer}(a::Array{T,2}, indent::Int=4)
lo, hi = extrema(a)
w = max(width(lo), width(hi))
id = " "^indent
fe = FormatExpr(@sprintf(" {:%dd}", w))
s = id
nrow = size(a)[1]
for i in 1:nrow
for j in a[i,:]
s *= format(fe, j)
end
i != nrow || continue
s *= "\n"*id
end
return s
end
println(pretty(a))

View file

@ -0,0 +1,26 @@
n = 5
println("The n = ", n, " zig-zag matrix:")
a = zeros(Int, (n, n))
for (i, s) in enumerate(zigzag(n))
a[s] = i-1
end
println(pretty(a))
m = 3
println()
println("Generalize to a non-square matrix (", m, "x", n, "):")
a = zeros(Int, (m, n))
for (i, s) in enumerate(zigzag(m, n))
a[s] = i-1
end
println(pretty(a))
p = primes(10^3)
n = 7
println()
println("An n = ", n, " prime spiral matrix:")
a = zeros(Int, (n, n))
for (i, s) in enumerate(zigzag(n))
a[s] = p[i]
end
println(pretty(a))

View file

@ -0,0 +1,67 @@
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.

View file

@ -0,0 +1,40 @@
Program zigzag;
{$APPTYPE CONSOLE}
const
size = 5;
var
s: array [1..size, 1..size] of integer;
i, j, d, max, n: integer;
begin
i := 1;
j := 1;
d := -1;
max := 0;
n := 0;
max := size * size;
for n := 1 to (max div 2)+1 do begin
s[i,j] := n;
s[size - i + 1,size - j + 1] := max - n + 1;
i:=i+d;
j:=j-d;
if i < 1 then begin
inc(i);
d := -d;
end else if j < 1 then begin
inc(j);
d := -d;
end;
end;
for j := 1 to size do
begin
for i := 1 to size do
write(s[i,j]:4);
writeln;
end;
end.

View file

@ -1,49 +0,0 @@
Program zigzag;
const
size = 5;
var
zzarray: array [1..size, 1..size] of integer;
element, i, j: integer;
direction: integer;
begin
i := 1;
j := 1;
direction := 1;
for element := 1 to size*size do
begin
zzarray[i,j] := element;
i := i + direction;
j := j - direction;
if (i = 0) then
begin
direction := -direction;
i := i + 1;
end;
if (i = size +1) then
begin
direction := -direction;
i := i - 1;
j := j + 2;
end;
if (j = 0) then
begin
direction := -direction;
j := j + 1;
end;
if (j = size + 1) then
begin
direction := -direction;
j := j - 1;
i := i + 2;
end;
end;
for j := 1 to size do
begin
for i := 1 to size do
write(zzarray[i,j]:3);
writeln;
end;
end.

View file

@ -0,0 +1,22 @@
\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

View file

@ -0,0 +1,65 @@
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)

View file

@ -1,26 +1,23 @@
/*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=='' then n=5 /*Not specified? Then use the default.*/
if start=='' then start=0 /* " " " " " " */
if inc=='' then inc=1 /* " " " " " " */
row=1; col=1 /*start with the 1st row, 1st column.*/
size=n**2 /*size of array.*/
/*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*/
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 element.*/
w=max(length(start), length(start + size*inc) ) /*maximum width of any matrix element. */
do row=1 for n; _= /*show all the rows of the matrix. */
do col=1 for n; _=_ right(@.row.col,w); end /*col*/
say _ /*show the matrix row just constructed.*/
end /*row*/ /*stick a fork in it, we're all done. */
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. */