2016 Update
This commit is contained in:
parent
948b86eafa
commit
dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions
|
|
@ -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 ''zig-zag'' array is a square arrangement of the first <big>N<sup>2</sup></big> integers, where the
|
||||
<br>numbers increase sequentially as you zig-zag along the array's [https://en.wiktionary.org/wiki/antidiagonal anti-diagonals].
|
||||
|
||||
For a graphical representation, see [[wp:Image:JPEG_ZigZag.svg|JPG zigzag]] (JPG uses such arrays to encode images).
|
||||
|
||||
|
||||
For example, given '''5''', 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:
|
||||
* [[Spiral matrix]]
|
||||
* [[Identity_matrix]]
|
||||
* [[Ulam_spiral_(for_primes)]]
|
||||
|
||||
|
||||
;See also:
|
||||
* Wiktionary entry: [https://en.wiktionary.org/wiki/antidiagonal anti-diagonals]
|
||||
<br><br>
|
||||
|
|
|
|||
58
Task/Zig-zag-matrix/ALGOL-W/zig-zag-matrix.alg
Normal file
58
Task/Zig-zag-matrix/ALGOL-W/zig-zag-matrix.alg
Normal 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.
|
||||
62
Task/Zig-zag-matrix/ATS/zig-zag-matrix.ats
Normal file
62
Task/Zig-zag-matrix/ATS/zig-zag-matrix.ats
Normal 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] *)
|
||||
|
||||
(* ****** ****** *)
|
||||
48
Task/Zig-zag-matrix/Agena/zig-zag-matrix.agena
Normal file
48
Task/Zig-zag-matrix/Agena/zig-zag-matrix.agena
Normal 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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
97
Task/Zig-zag-matrix/JavaScript/zig-zag-matrix-2.js
Normal file
97
Task/Zig-zag-matrix/JavaScript/zig-zag-matrix-2.js
Normal 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);
|
||||
5
Task/Zig-zag-matrix/JavaScript/zig-zag-matrix-3.js
Normal file
5
Task/Zig-zag-matrix/JavaScript/zig-zag-matrix-3.js
Normal 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]]
|
||||
60
Task/Zig-zag-matrix/JavaScript/zig-zag-matrix-4.js
Normal file
60
Task/Zig-zag-matrix/JavaScript/zig-zag-matrix-4.js
Normal 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);
|
||||
5
Task/Zig-zag-matrix/JavaScript/zig-zag-matrix-5.js
Normal file
5
Task/Zig-zag-matrix/JavaScript/zig-zag-matrix-5.js
Normal 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]]
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
26
Task/Zig-zag-matrix/Julia/zig-zag-matrix-4.julia
Normal file
26
Task/Zig-zag-matrix/Julia/zig-zag-matrix-4.julia
Normal 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))
|
||||
67
Task/Zig-zag-matrix/Pascal/zig-zag-matrix-1.pascal
Normal file
67
Task/Zig-zag-matrix/Pascal/zig-zag-matrix-1.pascal
Normal 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.
|
||||
40
Task/Zig-zag-matrix/Pascal/zig-zag-matrix-2.pascal
Normal file
40
Task/Zig-zag-matrix/Pascal/zig-zag-matrix-2.pascal
Normal 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.
|
||||
|
|
@ -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.
|
||||
22
Task/Zig-zag-matrix/PlainTeX/zig-zag-matrix.tex
Normal file
22
Task/Zig-zag-matrix/PlainTeX/zig-zag-matrix.tex
Normal 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
|
||||
65
Task/Zig-zag-matrix/Python/zig-zag-matrix-5.py
Normal file
65
Task/Zig-zag-matrix/Python/zig-zag-matrix-5.py
Normal 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)
|
||||
|
|
@ -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. */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue