Just another update

This commit is contained in:
Ingy döt Net 2015-02-20 00:35:01 -05:00
parent a25938f123
commit 00a190b0a6
6591 changed files with 94363 additions and 23227 deletions

View file

@ -1,4 +1,8 @@
Produce a spiral array. A spiral array is a square arrangement of the first <tt>N<sup>2</sup></tt> natural numbers, where the numbers increase sequentially as you go around the edges of the array spiralling inwards.
Produce a spiral array. <br>
A spiral array is a square arrangement of the
first <tt>N<sup>2</sup></tt> natural numbers,
where the numbers increase sequentially
as you go around the edges of the array spiralling inwards.
For example, given 5, produce this array:
<pre>
@ -8,3 +12,5 @@ For example, given 5, produce this array:
13 22 21 20 7
12 11 10 9 8
</pre>
;See also [[Zig-zag matrix]]

View file

@ -0,0 +1,120 @@
SPIRALM CSECT
USING SPIRALM,R13
SAVEAREA B STM-SAVEAREA(R15)
DC 17F'0'
DC CL8'SPIRALM'
STM STM R14,R12,12(R13)
ST R13,4(R15)
ST R15,8(R13)
LR R13,R15
* ---- CODE
LA R0,0
LA R1,1
LH R12,N n
LR R4,R1 Row=1
LR R5,R1 Col=1
LR R6,R1 BotRow=1
LR R7,R1 BotCol=1
LR R8,R12 TopRow=n
LR R9,R12 TopCol=n
LR R10,R0 Dir=0
LR R15,R12 n
MR R14,R12 R15=n*n
LA R11,1 k=1
LOOP CR R11,R15
BH ENDLOOP
LR R1,R4
BCTR R1,0
MH R1,N
AR R1,R5
LR R2,R11 k
BCTR R2,0
BCTR R1,0
SLA R1,1
STH R2,MATRIX(R1) Matrix(Row,Col)=k-1
CH R10,=H'0'
BE DIR0
CH R10,=H'1'
BE DIR1
CH R10,=H'2'
BE DIR2
CH R10,=H'3'
BE DIR3
B DIRX
DIR0 CR R5,R9 if Col<TopCol
BNL DIR0S
LA R5,1(R5) Col=Col+1
B DIRX
DIR0S LA R10,1 Dir=1
LA R4,1(R4) Row=Row+1
LA R6,1(R6) BotRow=BotRow+1
B DIRX
DIR1 CR R4,R8 if Row<TopRow
BNL DIR1S
LA R4,1(R4) Row=Row+1
B DIRX
DIR1S LA R10,2 Dir=2
BCTR R5,0 Col=Col-1
BCTR R9,0 TopCol=TopCol-1
B DIRX
DIR2 CR R5,R7 if Col>BotCol
BNH DIR2S
BCTR R5,0 Col=Col-1
B DIRX
DIR2S LA R10,3 Dir=3
BCTR R4,0 Row=Row-1
BCTR R8,0 TopRow=TopRow-1
B DIRX
DIR3 CR R4,R6 if Row>BotRow
BNH DIR3S
BCTR R4,0 Row=Row-1
B DIRX
DIR3S LA R10,0 Dir=0
LA R5,1(R5) Col=Col+1
LA R7,1(R7) BotCol=BotCol+1
DIRX EQU *
LA R11,1(R11) k=k+1
B LOOP
ENDLOOP EQU *
LA R4,1 i
LOOPI CR R4,R12
BH ENDLOOPI
XR R10,R10
LA R5,1 j
LOOPJ CR R5,R12
BH ENDLOOPJ
LR R1,R4
BCTR R1,0
MH R1,N
AR R1,R5
BCTR R1,0
SLA R1,1
LH R2,MATRIX(R1) Matrix(i,j)
LA R3,BUF
AR R3,R10
CVD R2,P8
MVC 0(4,R3),=X'40202120'
ED 0(4,R3),P8+6
LA R10,4(R10)
LA R5,1(R5)
B LOOPJ
ENDLOOPJ EQU *
WTO MF=(E,WTOMSG)
LA R4,1(R4)
B LOOPI
ENDLOOPI EQU *
* ---- END CODE
L R13,4(0,R13)
LM R14,R12,12(R13)
XR R15,R15
BR R14
* ---- DATA
N DC H'5' max=20 (20*4=80)
LTORG
P8 DS PL8
WTOMSG DS 0F
DC H'80',XL2'0000'
BUF DC CL80' '
MATRIX DS H Matrix(n,n)
YREGS
END SPIRALM

View file

@ -0,0 +1,17 @@
#include <vector>
#include <iostream>
using namespace std;
int main() {
const int n = 5;
const int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0};
int x = 0, y = -1, c = 0;
vector<vector<int>> m(n, vector<int>(n));
for (int i = 0, im = 0; i < n + n - 1; ++i, im = i % 4)
for (int j = 0, jlen = (n + n - i) / 2; j < jlen; ++j)
m[x += dx[im]][y += dy[im]] = ++c;
for (auto & r : m) {
for (auto & v : r)
cout << v << ' ';
cout << endl;
}
}

View file

@ -0,0 +1,18 @@
#include <stdio.h>
#include <stdlib.h>
int spiral(int w, int h, int x, int y)
{
return y ? w + spiral(h - 1, w, y - 1, w - x - 1) : x;
}
int main(int argc, char **argv)
{
int w = atoi(argv[1]), h = atoi(argv[2]), i, j;
for (i = 0; i < h; i++) {
for (j = 0; j < w; j++)
printf("%4d", spiral(w, h, j, i));
putchar('\n');
}
return 0;
}

View file

@ -1,8 +1,16 @@
(defn spiral [n]
(let [fmt (str " ~{~<~%~," (* n 3) ":;~2d ~>~}~%")
counts (cons n (mapcat #(repeat 2 %) (range (dec n) 0 -1)))
ones-and-ns (mapcat #(repeat %1 %2) counts (cycle [1 n -1 (- n)]))]
(->> (map vector (range 0 (* n n)) (reductions + ones-and-ns))
(let [cyc (cycle [1 n -1 (- n)])]
(->> (range (dec n) 0 -1)
(mapcat #(repeat 2 %))
(cons n)
#(mapcat repeat % cyc)
(reductions +)
(map vector (range 0 (* n n)))
(sort-by second)
(map first)
(clojure.pprint/cl-format true fmt))))
(map first)))
(let [n 5]
(clojure.pprint/cl-format
true
(str " ~{~<~%~," (* n 3) ":;~2d ~>~}~%")
(spiral n)))

View file

@ -1,12 +1,9 @@
module Spiral where
import Data.List
import Control.Monad
import Control.Monad.Instances
grade xs = map snd. sort $ zip xs [0..]
values n = cycle [1,n,-1,-n]
counts n = (n:).concatMap (ap (:) return) $ [n-1,n-2..1]
reshape n = unfoldr (\xs -> if null xs then Nothing else Just (splitAt n xs))
spiral n = reshape n . grade. scanl1 (+). concat $ zipWith replicate (counts n) (values n)
displayRow = putStrLn . intercalate " " . map show
main = mapM displayRow $ spiral 5

View file

@ -0,0 +1,9 @@
import Data.List
import Control.Applicative
counts = tail . reverse . concat . map (replicate 2) . enumFromTo 1
values = cycle . ((++) <$> map id <*> map negate) . (1 :) . (: [])
grade = map snd . sort . flip zip [0..]
copies = grade . scanl1 (+) . concat . map (uncurry replicate) . (zip <$> counts <*> values)
parts = (<*>) take $ (.) <$> (map . take) <*> (iterate . drop) <*> copies
disp = (>> return ()) . mapM (putStrLn . intercalate " " . map show) . parts
main = disp 5

View file

@ -0,0 +1,10 @@
import Data.List (transpose)
import Text.Printf (printf)
-- spiral is the first row plus a smaller spiral rotated 90 deg
spiral 0 _ _ = [[]]
spiral h w s = [[s .. s+w-1]] ++ rot90 (spiral w (h-1) (s+w))
where rot90 = (map reverse).transpose
-- this is sort of hideous, someone may want to fix it
main = mapM_ (\row->mapM_ ((printf "%4d").toInteger) row >> putStrLn "") (spiral 10 9 1)

View file

@ -1,4 +1,4 @@
spiral =. ,~ $ [: /: }.@(2 # >:@i.@-) +/\@# <:@+: $ (, -)@(1&,)
spiral =: ,~ $ [: /: }.@(2 # >:@i.@-) +/\@# <:@+: $ (, -)@(1&,)
spiral 5
0 1 2 3 4

View file

@ -0,0 +1,70 @@
program Spiralmat;
type
tDir = (left,down,right,up);
tdxy = record
dx,dy: longint;
end;
tdeltaDir = array[tDir] of tdxy;
const
Nextdir : array[tDir] of tDir = (down,right,up,left);
cDir : tDeltaDir = ((dx:1;dy:0),(dx:0;dy:1),(dx:-1;dy:0),(dx:0;dy:-1));
cMaxN = 32;
type
tSpiral = array[0..cMaxN,0..cMaxN] of LongInt;
function FillSpiral(n:longint):tSpiral;
var
b,i,k, dn,x,y : longInt;
dir : tDir;
tmpSp : tSpiral;
BEGIN
b := 0;
x := 0;
y := 0;
//only for the first line
k := -1;
dn := n-1;
tmpSp[x,y] := b;
dir := left;
repeat
i := 0;
while i < dn do
begin
inc(b);
tmpSp[x,y] := b;
inc(x,cDir[dir].dx);
inc(y,cDir[dir].dy);
inc(i);
end;
Dir:= NextDir[dir];
inc(k);
IF k > 1 then
begin
k := 0;
//shorten the line every second direction change
dn := dn-1;
if dn <= 0 then
BREAK;
end;
until false;
//the last
tmpSp[x,y] := b+1;
FillSpiral := tmpSp;
end;
var
a : tSpiral;
x,y,n : LongInt;
BEGIN
For n := 1 to 5{cMaxN} do
begin
A:=FillSpiral(n);
For y := 0 to n-1 do
begin
For x := 0 to n-1 do
write(A[x,y]:4);
writeln;
end;
writeln;
end;
END.

View file

@ -1,16 +1,18 @@
def spiral(n):
dat = [[None] * n for i in range(n)]
le = [[i + 1, i + 1] for i in reversed(range(n))]
le = sum(le, [])[1:] # for n = 5 le will be [5, 4, 4, 3, 3, 2, 2, 1, 1]
dxdy = [[1, 0], [0, 1], [-1, 0], [0, -1]] * ((len(le) + 4) / 4) # long enough
x, y, val = -1, 0, -1
for steps, (dx, dy) in zip(le, dxdy):
x, y, val = x + dx, y + dy, val + 1
for j in range(steps):
dat[y][x] = val
if j != steps-1:
x, y, val = x + dx, y + dy, val + 1
return dat
def rot_right(a):
return zip(*a[::-1])
for row in spiral(5): # calc spiral and print it
print ' '.join('%3s' % x for x in row)
def sp(m, n, start = 0):
""" Generate number range spiral of dimensions m x n
"""
if n == 0:
yield ()
else:
yield tuple(range(start, m + start))
for row in rot_right(list(sp(n - 1, m, m + start))):
yield row
def spiral(m):
return sp(m, m)
for row in spiral(5):
print(''.join('%3i' % i for i in row))

View file

@ -1,19 +1,16 @@
import itertools
def spiral(n):
dat = [[None] * n for i in range(n)]
le = [[i + 1, i + 1] for i in reversed(range(n))]
le = sum(le, [])[1:] # for n = 5 le will be [5, 4, 4, 3, 3, 2, 2, 1, 1]
dxdy = [[1, 0], [0, 1], [-1, 0], [0, -1]] * ((len(le) + 4) / 4) # long enough
x, y, val = -1, 0, -1
for steps, (dx, dy) in zip(le, dxdy):
x, y, val = x + dx, y + dy, val + 1
for j in range(steps):
dat[y][x] = val
if j != steps-1:
x, y, val = x + dx, y + dy, val + 1
return dat
concat = itertools.chain.from_iterable
def partial_sums(items):
s = 0
for x in items:
s += x
yield s
grade = lambda xs: sorted(range(len(xs)), key=xs.__getitem__)
values = lambda n: itertools.cycle([1,n,-1,-n])
counts = lambda n: concat([i,i-1] for i in range(n,0,-1))
reshape = lambda n, xs: zip(*([iter(xs)] * n))
spiral = lambda n: reshape(n, grade(list(partial_sums(concat(
[v]*c for c,v in zip(counts(n), values(n)))))))
for row in spiral(5):
print(' '.join('%3s' % x for x in row))
for row in spiral(5): # calc spiral and print it
print ' '.join('%3s' % x for x in row)

View file

@ -0,0 +1,19 @@
import itertools
concat = itertools.chain.from_iterable
def partial_sums(items):
s = 0
for x in items:
s += x
yield s
grade = lambda xs: sorted(range(len(xs)), key=xs.__getitem__)
values = lambda n: itertools.cycle([1,n,-1,-n])
counts = lambda n: concat([i,i-1] for i in range(n,0,-1))
reshape = lambda n, xs: zip(*([iter(xs)] * n))
spiral = lambda n: reshape(n, grade(list(partial_sums(concat(
[v]*c for c,v in zip(counts(n), values(n)))))))
for row in spiral(5):
print(' '.join('%3s' % x for x in row))

View file

@ -0,0 +1,11 @@
n = 5
dx, dy = [0, 1, 0, -1], [1, 0, -1, 0]
x, y, c = 0, -1, 1
m = [[0 for i in range(n)] for j in range(n)]
for i in range(n + n - 1):
for j in range((n + n - i) // 2):
x += dx[i % 4]
y += dy[i % 4]
m[x][y] = c
c += 1
print('\n'.join([' '.join([str(v) for v in r]) for r in m]))

View file

@ -0,0 +1,22 @@
/*REXX program displays a spiral in a square array (of any size). */
parse arg size . /*get the array size from the CL.*/
if size=='' then size=5 /*No argument? Then use default.*/
tot=size**2 /*total # of elements in spiral.*/
k=size /*K is the counter for the spiral*/
row=1; col=0; start=0 /*start at row 1, col 0, with 0.*/
/*──────────────────────────────────────────────construct the spiral #s.*/
do n=start for k; col=col+1; @.col.row=n; end; if k==0 then exit
/* [↑] build first row of spiral*/
do until n>=tot /*spiral matrix.*/
do one=1 to -1 by -2 until n>=tot; k=k-1 /*perform twice.*/
do n=n for k; row=row+one; @.col.row=n; end /*for the row···*/
do n=n for k; col=col-one; @.col.row=n; end /* " " col···*/
end /*one*/ /* ↑↓ direction.*/
end /*until n≥tot*/ /* [↑] done with matrix spiral.*/
/*──────────────────────────────────────────────display spiral to screen*/
do row=1 for size; _= /*construct display row by row.*/
do col=1 for size /*construct a line col by col.*/
_=_ right(@.col.row, length(tot)) /*construct a line for display. */
end /*col*/ /* [↑] line has an extra blank.*/
say substr(_,2) /*SUBSTR ignores the first blank.*/
end /*row*/ /*stick a fork in it, we're done.*/

View file

@ -0,0 +1,25 @@
/*REXX program displays a spiral in a square array (of any size). */
parse arg size . /*get the array size from the CL.*/
if size=='' then size=5 /*No argument? Then use default.*/
tot=size**2 /*total # of elements in spiral.*/
k=size /*K is the counter for the spiral*/
row=1; col=0; start=0 /*start at row 1, col 0, with 0.*/
/*──────────────────────────────────────────────construct the spiral #s.*/
do n=start for k; col=col+1; @.col.row=n; end; if k==0 then exit
/* [↑] build first row of spiral*/
do until n>=tot /*spiral matrix.*/
do one=1 to -1 by -2 until n>=tot; k=k-1 /*perform twice.*/
do n=n for k; row=row+one; @.col.row=n; end /*for the row···*/
do n=n for k; col=col-one; @.col.row=n; end /* " " col···*/
end /*one*/ /* ↑↓ direction.*/
end /*until n≥tot*/ /* [↑] done with matrix spiral.*/
/*──────────────────────────────────────────────display spiral to screen*/
do twice=0 for 2; if \twice then !.=0 /*1st time? Find max col width.*/
do row=1 for size; _= /*construct display row by row. */
do col=1 for size; x=@.col.row /*construct a line col by col. */
if twice then _=_ right(x,!.col) /*construct a line for display.*/
else !.col=max(!.col,length(x)) /*find width of column*/
end /*col*/ /* [↓] line has an extra blank.*/
if twice then say substr(_,2) /*SUBSTR ignores the 1st blank. */
end /*row*/ /*stick a fork in it, we're done*/
end /*twice*/

View file

@ -1,27 +0,0 @@
/*REXX program displays a spiral in a square array (of any size). */
parse arg size . /*get the array size from arg. */
if size=='' then size=5 /*if no argument, use the default*/
tot=size**2 /*total # of elements in spiral. */
k=size /*K is the counter for the sprial*/
row=1; col=0 /*start with row one, col zero. */
n=0 /*start the spiral at 0 (zero).*/
/*─────────────────────────────────────build the spiral */
do n=0 for k; col=col+1; @.col.row=n; end; if k==0 then exit
do until n>=tot
k=k-1
do n=n for k; row=row+1; @.col.row=n; end
do n=n for k; col=col-1; @.col.row=n; end
if n>=tot then leave
k=k-1
do n=n for k; row=row-1; @.col.row=n; end
do n=n for k; col=col+1; @.col.row=n; end
end /*DO until n≥tot*/
/*─────────────────────────────────────display the spiral */
do col=1 for size; _=
do row=1 for size
_=_ right(@.row.col, length(tot))
end /*row*/
say substr(_,2)
end /*col*/
/*stick a fork in it, we're done.*/

View file

@ -11,8 +11,8 @@ def spiral(n)
end
def print_matrix(m)
max = m.flatten.map{|x| x.to_s.size}.max
m.each {|row| puts row.map {|x| "%#{max}s " % x}.join}
width = m.flatten.map{|x| x.to_s.size}.max
m.each {|row| puts row.map {|x| "%#{width}s " % x}.join}
end
print_matrix spiral(5)

View file

@ -0,0 +1,13 @@
n = 5
m = Array.new(n){Array.new(n)}
pos, side = -1, n
for i in 0 .. (n-1)/2
(0...side).each{|j| m[i][i+j] = (pos+=1) }
(1...side).each{|j| m[i+j][n-1-i] = (pos+=1) }
side -= 2
side.downto(0) {|j| m[n-1-i][i+j] = (pos+=1) }
side.downto(1) {|j| m[i+j][i] = (pos+=1) }
end
fmt = "%#{(n*n-1).to_s.size}d " * n
puts m.map{|row| fmt % row}

View file

@ -0,0 +1,22 @@
// Spiral Matrix
n=10
mat=zeros(n,n);
botcol=1; topcol=n
botrow=1; toprow=n
ndir=0; col=1; row=1;
for i=0:n*n-1
mat(row,col)=i;
if ndir==0
if col<topcol then col=col+1; else ndir=1, row=row+1; botrow=botrow+1; end
elseif ndir==1
if row<toprow then row=row+1; else ndir=2, col=col-1; topcol=topcol-1; end
elseif ndir==2
if col>botcol then col=col-1; else ndir=3, row=row-1; toprow=toprow-1; end
elseif ndir==3
if row>botrow then row=row-1; else ndir=0, col=col+1; botcol=botcol+1; end
end
end i
printf("n=%4d\n",n);
for i=1:n;
for j=1:n; printf("%4d",mat(i,j)); end j; printf("\n");
end i;

View file

@ -0,0 +1,40 @@
5->N
DelVar [F]
{N,N}→dim([F])
1→A: N→B
1→C: N→D
0→E: E→G
1→I: 1→J
For(K,1,N*N)
K-1→[F](I,J)
If E=0: Then
If J<D: Then
J+1→J
Else: 1→G
I+1→I: A+1→A
End
End
If E=1: Then
If I<B: Then
I+1→I
Else: 2→G
J-1→J: D-1→D
End
End
If E=2: Then
If J>C: Then
J-1→J
Else: 3→G
I-1→I: B-1→B
End
End
If E=3: Then
If I>A: Then
I-1→I
Else: 0→G
J+1→J: C+1→C
End
End
G→E
End
[F]

View file

@ -0,0 +1,55 @@
Module modSpiralArray
Sub Main()
print2dArray(getSpiralArray(5))
End Sub
Function getSpiralArray(dimension As Integer) As Object
Dim spiralArray(,) As Integer
Dim numConcentricSquares As Integer
ReDim spiralArray(dimension - 1, dimension - 1)
numConcentricSquares = dimension \ 2
If (dimension Mod 2) Then numConcentricSquares = numConcentricSquares + 1
Dim j As Integer, sideLen As Integer, currNum As Integer
sideLen = dimension
Dim i As Integer
For i = 0 To numConcentricSquares - 1
' do top side
For j = 0 To sideLen - 1
spiralArray(i, i + j) = currNum
currNum = currNum + 1
Next
' do right side
For j = 1 To sideLen - 1
spiralArray(i + j, dimension - 1 - i) = currNum
currNum = currNum + 1
Next
' do bottom side
For j = sideLen - 2 To 0 Step -1
spiralArray(dimension - 1 - i, i + j) = currNum
currNum = currNum + 1
Next
' do left side
For j = sideLen - 2 To 1 Step -1
spiralArray(i + j, i) = currNum
currNum = currNum + 1
Next
sideLen = sideLen - 2
Next
getSpiralArray = spiralArray
End Function
Sub print2dArray(arr)
Dim row As Integer, col As Integer, s As String
For row = 0 To UBound(arr, 1)
s = ""
For col = 0 To UBound(arr, 2)
s = s & " " & Right(" " & arr(row, col), 3)
Next
Debug.Print(s)
Next
End Sub
End Module