package require Tcl 8.5
package require math::constants
math::constants::constants pi
proc tcl::mathfunc::randf m {expr {$m * rand()}}

proc genXY {count radius} {
    global pi
    for {set i 0} {$i < $count} {incr i} {
	set ang [expr {randf(2 * $pi)}]
	set r [expr {randf($radius)}]
	lappend pt [list [expr {$r*cos($ang)}] [expr {$r*sin($ang)}] -1]
    }
    return $pt
}
proc dist2 {a b} {
    lassign $a ax ay
    lassign $b bx by
    return [expr {($ax-$bx)**2 + ($ay-$by)**2}]
}

proc nearest {pt cent {d2var ""}} {
    set minD 1e30
    set minI [lindex $pt 2]
    set i -1
    foreach c $cent {
	incr i
	set d [dist2 $c $pt]
	if {$minD > $d} {
	    set minD $d
	    set minI $i
	}
    }
    if {$d2var ne ""} {
	upvar 1 $d2var d2
	set d2 $minD
    }
    return $minI
}

proc kpp {ptsVar centVar numClusters} {
    upvar 1 $ptsVar pts $centVar cent
    set idx [expr {int([llength $pts] * rand())}]
    set cent [list [lindex $pts $idx]]
    for {set nCent 1} {$nCent < $numClusters} {incr nCent} {
	set sum 0
	set d {}
	foreach p $pts {
	    nearest $p $cent dd
	    set sum [expr {$sum + $dd}]
	    lappend d $dd
	}
	set sum [expr {randf($sum)}]
	foreach p $pts dj $d {
	    set sum [expr {$sum - $dj}]
	    if {$sum <= 0} {
		lappend cent $p
		break
	    }
	}
    }
    set i -1
    foreach p $pts {
	lset pts [incr i] 2 [nearest $p $cent]
    }
}

proc lloyd {ptsVar numClusters} {
    upvar 1 $ptsVar pts
    kpp pts cent $numClusters
    while 1 {
	# Find centroids for round
	set groupCounts [lrepeat [llength $cent] 0]
	foreach p $pts {
	    lassign $p cx cy group
	    lset groupCounts $group [expr {[lindex $groupCounts $group] + 1}]
	    lset cent $group 0 [expr {[lindex $cent $group 0] + $cx}]
	    lset cent $group 1 [expr {[lindex $cent $group 1] + $cy}]
	}
	set i -1
	foreach groupn $groupCounts {
	    incr i
	    lset cent $i 0 [expr {[lindex $cent $i 0] / $groupn}]
	    lset cent $i 1 [expr {[lindex $cent $i 1] / $groupn}]
	}

	set changed 0
	set i -1
	foreach p $pts {
	    incr i
	    set minI [nearest $p $cent]
	    if {$minI != [lindex $p 2]} {
		incr changed
		lset pts $i 2 $minI
	    }
	}
	if {$changed < ([llength $pts] >> 10)} break
    }
    set i -1
    foreach c $cent {
	lset cent [incr i] 2 $i
    }
    return $cent
}


(load "@lib/simul.l")

# Build board
(grid 8 8)

# Generate legal moves for a given position
(de moves (Tour)
   (extract
      '((Jump)
         (let? Pos (Jump (car Tour))
            (unless (memq Pos Tour)
               Pos ) ) )
      (quote  # (taken from "games/chess.l")
         ((This) (: 0 1  1  0 -1  1  0 -1  1))        # South Southwest
         ((This) (: 0 1  1  0 -1  1  0  1  1))        # West Southwest
         ((This) (: 0 1  1  0 -1 -1  0  1  1))        # West Northwest
         ((This) (: 0 1  1  0 -1 -1  0 -1 -1))        # North Northwest
         ((This) (: 0 1 -1  0 -1 -1  0 -1 -1))        # North Northeast
         ((This) (: 0 1 -1  0 -1 -1  0  1 -1))        # East Northeast
         ((This) (: 0 1 -1  0 -1  1  0  1 -1))        # East Southeast
         ((This) (: 0 1 -1  0 -1  1  0 -1  1)) ) ) )  # South Southeast

# Build a list of moves, using Warnsdorff’s algorithm
(let Tour '(b1)  # Start at b1
   (while
      (mini
         '((P) (length (moves (cons P Tour))))
         (moves Tour) )
      (push 'Tour @) )
   (flip Tour) )


import "random" for Random
import "/dynamic" for Struct
import "/fmt" for Fmt

var Point = Struct.create("Point", ["x", "y", "group"])

var r = Random.new()
var hugeVal = Num.infinity

var RAND_MAX = Num.maxSafeInteger
var PTS = 100000
var K = 11
var W = 400
var H = 400

var rand = Fn.new { r.int(RAND_MAX) }
var randf = Fn.new { |m| m * rand.call() / (RAND_MAX - 1) }

var genXY = Fn.new { |count, radius|
    var pts = List.filled(count, null)

    /* note: this is not a uniform 2-d distribution */
    for (i in 0...count) {
        pts[i] = Point.new(0, 0, 0)
        var ang = randf.call(2 * Num.pi)
        var r = randf.call(radius)
        pts[i].x = r * ang.cos
        pts[i].y = r * ang.sin
    }
    return pts
}

var dist2 = Fn.new { |a, b|
    var x = a.x - b.x
    var y = a.y - b.y
    return x * x + y * y
}

var nearest = Fn.new { |pt, cent, nCluster|
    var minD = hugeVal
    var minI = pt.group
    for (i in 0...nCluster) {
        var d = dist2.call(cent[i], pt)
        if (minD > d) {
            minD = d
            minI = i
        }
    }
    return [minI, minD]
}

var copyPoint = Fn.new { |pt| Point.new(pt.x, pt.y, pt.group) }

var kpp = Fn.new { |pts, len, cent|
    var nCent = cent.count
    var d = List.filled(len, 0)
    cent[0] = copyPoint.call(pts[rand.call() % len])
    for (nCluster in 1...nCent) {
        var sum = 0
        for (j in 0...len) {
            d[j] = nearest.call(pts[j], cent, nCluster)[1]
            sum = sum + d[j]
        }
        sum = randf.call(sum)
        for (j in 0...len) {
            sum = sum - d[j]
            if (sum > 0) continue
            cent[nCluster] = copyPoint.call(pts[j])
            break
        }
    }
    for (j in 0...len) pts[j].group = nearest.call(pts[j], cent, nCent)[0]
}

var lloyd = Fn.new { |pts, len, nCluster|
    var cent = List.filled(nCluster, null)
    for (i in 0...nCluster) cent[i] = Point.new(0, 0, 0)
    kpp.call(pts, len, cent)
    while(true) {
        /* group element for centroids are used as counters */
        for (i in 0...nCluster) {
            cent[i].x = 0
            cent[i].y = 0
            cent[i].group = 0
        }
        for (j in 0...len) {
            var p = pts[j]
            var c = cent[p.group]
            c.group = c.group + 1
            c.x = c.x + p.x
            c.y = c.y + p.y
        }
        for (i in 0...nCluster) {
            var c = cent[i]
            c.x = c.x / c.group
            c.y = c.y / c.group
        }
        var changed = 0

        /* find closest centroid of each point */
        for (j in 0...len) {
            var p = pts[j]
            var minI = nearest.call(p, cent, nCluster)[0]
            if (minI != p.group) {
                changed = changed + 1
                p.group = minI
            }
        }

        /* stop when 99.9% of points are good */
        if (changed <= (len >> 10)) break
    }
    for (i in 0...nCluster) cent[i].group = i
    return cent
}

var printEps = Fn.new { |pts, len, cent, nCluster|
    var colors = List.filled(nCluster * 3, 0)
    for (i in 0...nCluster) {
        colors[3 * i + 0] = (3 * (i + 1) % 11) / 11
        colors[3 * i + 1] = (7 * i % 11) / 11
        colors[3 * i + 2] = (9 * i % 11) / 11
    }
    var minX = hugeVal
    var minY = hugeVal
    var maxX = -hugeVal
    var maxY = -hugeVal
    for (j in 0...len) {
        var p = pts[j]
        if (maxX < p.x) maxX = p.x
        if (minX > p.x) minX = p.x
        if (maxY < p.y) maxY = p.y
        if (minY > p.y) minY = p.y
    }
    var scale = (W / (maxX - minX)).min(H / (maxY - minY))
    var cx = (maxX + minX) / 2
    var cy = (maxY + minY) / 2

    System.print("\%!PS-Adobe-3.0\n\%\%BoundingBox: -5 -5 %(W + 10) %(H + 10)")
    System.print("/l {rlineto} def /m {rmoveto} def")
    System.print("/c { .25 sub exch .25 sub exch .5 0 360 arc fill } def")
    System.write("/s { moveto -2 0 m 2 2 l 2 -2 l -2 -2 l closepath ")
    System.write("     gsave 1 setgray fill grestore gsave 3 setlinewidth")
    System.print(" 1 setgray stroke grestore 0 setgray stroke }def")
    var f1 = "$g $g $g setrgbcolor"
    var f2 = "$.3f $.3f c"
    var f3 = "\n0 setgray $g $g s"
    for (i in 0...nCluster) {
        var c = cent[i]
        Fmt.print(f1, colors[3 * i], colors[3 * i + 1], colors[3 * i + 2])
        for (j in 0...len) {
            var p = pts[j]
            if (p.group != i) continue
            Fmt.print(f2, (p.x - cx) * scale + W / 2, (p.y - cy) * scale + H / 2)
        }
        Fmt.print(f3, (c.x - cx) * scale + W / 2, (c.y - cy) * scale + H / 2)
    }
    System.write("\n\%\%EOF")
}

var v = genXY.call(PTS, 10)
var c = lloyd.call(v, PTS, K)
printEps.call(v, PTS, c, K)


%!PS-Adobe-3.0
%%BoundingBox: 0 0 300 300

/s { 300 n div } def
/l { rlineto } def

% draws a square
/bx { s mul exch s mul moveto s 0 l 0 s l s neg 0 l 0 s neg l } def

% draws checker board
/xbd {  1 setgray
        0 0 moveto 300 0 l 0 300 l -300 0 l fill
        .7 1 .6 setrgbcolor
        0 1 n1 { dup 2 mod 2 n1 { 1 index bx fill } for pop } for
        0 setgray
} def

/ar1 { [ exch { 0 } repeat ] } def
/ar2 { [ exch dup { dup ar1 exch } repeat pop ] } def

/neighbors {
        -1  2 0
         1  2 0
         2  1 0
         2 -1 0
         1 -2 0
        -1 -2 0
        -2 -1 0
        -2  1 0
        %24 x y add 3 mul roll
} def

/func { 0 dict begin mark } def
/var { counttomark -1 1 { 2 add -1 roll def } for cleartomark } def

% x y can_goto -> bool
/can_goto {
        func /x /y var
        x 0     ge
        x n     lt
        y 0     ge
        y n     lt
        and and and {
                occupied x get y get 0 eq
        } { false } ifelse
        end
} def

% x y num_access -> number of cells reachable from (x,y)
/num_access {
        func /x /y var
        /count 0 def
        x y can_goto {
                neighbors
                8 { pop y add exch x add exch can_goto {
                                /count count 1 add def
                        } if
                } repeat
                count 0 gt { count } { 9 } ifelse
        } { 10 } ifelse
        end
} def

% a circle
/marker { x s mul y s mul s 20 div 0 360 arc fill } def

% n solve -> draws board of size n x n, calcs path and draws it
/solve {
        func /n var
        /n1 n 1 sub def

        /c false def

        8 n div setlinewidth
        gsave

        0 1 n1 { /x exch def c not {
        0 1 n1 {
                /occupied n ar2 def
                c not {
                        /c true def
                        /y exch def
                        grestore xbd gsave
                        s 2 div dup translate
                        n n mul 2 sub -1 0 { /iter exch def
                                c {
                                0 setgray marker x s mul y s mul moveto
                                occupied x get y 1 put
                                neighbors
                                8 { pop y add exch x add exch 2 copy num_access 24 3 roll } repeat
                                7 { dup 4 index lt { 6 3 roll } if pop pop pop } repeat

                                9 ge iter 0 gt and { /c false def } if
                                /y exch def
                                /x exch def
                                .2 setgray x s mul y s mul lineto stroke
                        } if } for
                        % to be nice, draw box at final position
                        .5 0 0 setrgbcolor marker
                        y .5 sub x .5 sub bx 1 setlinewidth stroke
                        stroke
                } if
        } for } if } for showpage
        grestore
        end
} def

3 1 100 { solve } for

%%EOF


include c:\cxpl\codes;  \intrinsic 'code' declarations

def     N = 30000;              \number of points
def     K = 6;                  \number of clusters
int     Px(N), Py(N), Pc(N),    \coordinates of points and their cluster
        Cx(K), Cy(K);           \coordinates of centroid of cluster

func Centroid;  \Find new centroids of points grouped with current centroids
int  Change, Cx0(K), Cy0(K), C, Count, I;
[Change:= false;
for C:= 0 to K-1 do                       \for each centroid...
        [Cx0(C):= Cx(C);  Cy0(C):= Cy(C); \save current centroid
        Cx(C):= 0;  Cx(C):= 0;  Count:= 0;\find new centroid
        for I:= 0 to N-1 do               \for all points
            if Pc(I) = C then             \ grouped with current centroid...
                [Cx(C):= Cx(C) + Px(I);
                 Cy(C):= Cy(C) + Py(I);
                 Count:= Count+1;
                ];
        Cx(C):= Cx(C)/Count;  Cy(C):= Cy(C)/Count;
        if Cx(C)#Cx0(C) or Cy(C)#Cy0(C) then Change:= true;
        ];
return Change;
];

proc Voronoi;                   \Group points with their nearest centroid
int  D2, MinD2, I, C;           \distance squared, minimum distance squared
[for I:= 0 to N-1 do            \for each point...
        [MinD2:= -1>>1;         \find closest centroid
        for C:= 0 to K-1 do
                [D2:= sq(Px(I)-Cx(C)) + sq(Py(I)-Cy(C));
                if D2 < MinD2 then
                        [MinD2:= D2;  Pc(I):= C];  \update closest centroid
                ];
        ];
];

proc KMeans;                    \Group points into K clusters
int  Change, I;
repeat  Voronoi;
        Change:= Centroid;
        SetVid($101);           \show result on 640x480x8 screen
        for I:= 0 to N-1 do Point(Px(I), Py(I), Pc(I)+1);
        for I:= 0 to K-1 do Point(Cx(I), Cy(I), \bright white\ $F);
until   Change = false;

proc Random(X, Y);              \Return random X,Y biased for polar coordinates
int  X, Y;
real A, D;
[D:= float(Ran(240));                   \distance: 0..239
A:= float(Ran(314159*2)) / 10000.0;     \angle:    0..2pi
X(0):= fix(D*Cos(A)) + 320;             \rectangular coords centered on screen
Y(0):= fix(D*Sin(A)) + 240;
];

int  I;
[for I:= 0 to N-1 do Random(@Px(I), @Py(I));    \random set of points
 for I:= 0 to K-1 do Random(@Cx(I), @Cy(I));    \random set of cluster centroids
KMeans;
I:= ChIn(1);                    \wait for keystroke
SetVid($03);                    \restore normal text screen
]


% N is the number of lines of the chessboard
knight(N) :-
	Max is N * N,
	length(L, Max),
	knight(N, 0, Max, 0, 0, L),
	display(N, 0, L).

% knight(NbCol, Coup, Max, Lig, Col, L),
% NbCol : number of columns per line
% Coup  : number of the current move
% Max   : maximum number of moves
% Lig/ Col : current position of the knight
% L : the "chessboard"

% the game is over
knight(_, Max, Max, _, _, _) :- !.

knight(NbCol, N, MaxN, Lg, Cl, L) :-
	% Is the move legal
	Lg >= 0, Cl >= 0, Lg < NbCol, Cl < NbCol,

	Pos is Lg * NbCol + Cl,
	N1 is N+1,
	% is the place free
	nth0(Pos, L, N1),

	LgM1 is Lg - 1, LgM2 is Lg - 2, LgP1 is Lg + 1, LgP2 is Lg + 2,
	ClM1 is Cl - 1, ClM2 is Cl - 2, ClP1 is Cl + 1, ClP2 is Cl + 2,
	maplist(best_move(NbCol, L),
		[(LgP1, ClM2), (LgP2, ClM1), (LgP2, ClP1),(LgP1, ClP2),
		 (LgM1, ClM2), (LgM2, ClM1), (LgM2, ClP1),(LgM1, ClP2)],
		R),
	sort(R, RS),
	pairs_values(RS, Moves),

	move(NbCol, N1, MaxN, Moves, L).

move(NbCol, N1, MaxN, [(Lg, Cl) | R], L) :-
	knight(NbCol, N1, MaxN, Lg, Cl, L);
	move(NbCol, N1, MaxN,  R, L).

%% An illegal move is scored 1000
best_move(NbCol, _L, (Lg, Cl), 1000-(Lg, Cl)) :-
	(   Lg < 0 ; Cl < 0; Lg >= NbCol; Cl >= NbCol), !.

best_move(NbCol, L, (Lg, Cl), 1000-(Lg, Cl)) :-
	Pos is Lg*NbCol+Cl,
	nth0(Pos, L, V),
	\+var(V), !.

%% a legal move is scored with the number of moves a knight can make
best_move(NbCol, L, (Lg, Cl), R-(Lg, Cl)) :-
	LgM1 is Lg - 1, LgM2 is Lg - 2, LgP1 is Lg + 1, LgP2 is Lg + 2,
	ClM1 is Cl - 1, ClM2 is Cl - 2, ClP1 is Cl + 1, ClP2 is Cl + 2,
	include(possible_move(NbCol, L),
		[(LgP1, ClM2), (LgP2, ClM1), (LgP2, ClP1),(LgP1, ClP2),
		 (LgM1, ClM2), (LgM2, ClM1), (LgM2, ClP1),(LgM1, ClP2)],
		Res),
	length(Res, Len),
	(   Len = 0 -> R = 1000; R = Len).

% test if a place is enabled
possible_move(NbCol, L, (Lg, Cl)) :-
	% move must be legal
	Lg >= 0, Cl >= 0, Lg < NbCol, Cl < NbCol,
	Pos is Lg * NbCol + Cl,
	% place must be free
	nth0(Pos, L, V),
	var(V).

display(_, _, []).
display(N, N, L) :-
	nl,
	display(N, 0, L).

display(N, M, [H | T]) :-
	writef('%3r', [H]),
	M1 is M + 1,
	display(N, M1, T).


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>

#define MAX_DIM 3
struct kd_node_t{
    double x[MAX_DIM];
    struct kd_node_t *left, *right;
};

    inline double
dist(struct kd_node_t *a, struct kd_node_t *b, int dim)
{
    double t, d = 0;
    while (dim--) {
        t = a->x[dim] - b->x[dim];
        d += t * t;
    }
    return d;
}
inline void swap(struct kd_node_t *x, struct kd_node_t *y) {
    double tmp[MAX_DIM];
    memcpy(tmp,  x->x, sizeof(tmp));
    memcpy(x->x, y->x, sizeof(tmp));
    memcpy(y->x, tmp,  sizeof(tmp));
}

/* see quickselect method */
    struct kd_node_t*
find_median(struct kd_node_t *start, struct kd_node_t *end, int idx)
{
    if (end <= start) return NULL;
    if (end == start + 1)
        return start;

    struct kd_node_t *p, *store, *md = start + (end - start) / 2;
    double pivot;
    while (1) {
        pivot = md->x[idx];

        swap(md, end - 1);
        for (store = p = start; p < end; p++) {
            if (p->x[idx] < pivot) {
                if (p != store)
                    swap(p, store);
                store++;
            }
        }
        swap(store, end - 1);

        /* median has duplicate values */
        if (store->x[idx] == md->x[idx])
            return md;

        if (store > md) end = store;
        else        start = store;
    }
}

    struct kd_node_t*
make_tree(struct kd_node_t *t, int len, int i, int dim)
{
    struct kd_node_t *n;

    if (!len) return 0;

    if ((n = find_median(t, t + len, i))) {
        i = (i + 1) % dim;
        n->left  = make_tree(t, n - t, i, dim);
        n->right = make_tree(n + 1, t + len - (n + 1), i, dim);
    }
    return n;
}

/* global variable, so sue me */
int visited;

void nearest(struct kd_node_t *root, struct kd_node_t *nd, int i, int dim,
        struct kd_node_t **best, double *best_dist)
{
    double d, dx, dx2;

    if (!root) return;
    d = dist(root, nd, dim);
    dx = root->x[i] - nd->x[i];
    dx2 = dx * dx;

    visited ++;

    if (!*best || d < *best_dist) {
        *best_dist = d;
        *best = root;
    }

    /* if chance of exact match is high */
    if (!*best_dist) return;

    if (++i >= dim) i = 0;

    nearest(dx > 0 ? root->left : root->right, nd, i, dim, best, best_dist);
    if (dx2 >= *best_dist) return;
    nearest(dx > 0 ? root->right : root->left, nd, i, dim, best, best_dist);
}

#define N 1000000
#define rand1() (rand() / (double)RAND_MAX)
#define rand_pt(v) { v.x[0] = rand1(); v.x[1] = rand1(); v.x[2] = rand1(); }
int main(void)
{
    int i;
    struct kd_node_t wp[] = {
        {{2, 3}}, {{5, 4}}, {{9, 6}}, {{4, 7}}, {{8, 1}}, {{7, 2}}
    };
    struct kd_node_t testNode = {{9, 2}};
    struct kd_node_t *root, *found, *million;
    double best_dist;

    root = make_tree(wp, sizeof(wp) / sizeof(wp[1]), 0, 2);

    visited = 0;
    found = 0;
    nearest(root, &testNode, 0, 2, &found, &best_dist);

    printf(">> WP tree\nsearching for (%g, %g)\n"
            "found (%g, %g) dist %g\nseen %d nodes\n\n",
            testNode.x[0], testNode.x[1],
            found->x[0], found->x[1], sqrt(best_dist), visited);

    million =(struct kd_node_t*) calloc(N, sizeof(struct kd_node_t));
    srand(time(0));
    for (i = 0; i < N; i++) rand_pt(million[i]);

    root = make_tree(million, N, 0, 3);
    rand_pt(testNode);

    visited = 0;
    found = 0;
    nearest(root, &testNode, 0, 3, &found, &best_dist);

    printf(">> Million tree\nsearching for (%g, %g, %g)\n"
            "found (%g, %g, %g) dist %g\nseen %d nodes\n",
            testNode.x[0], testNode.x[1], testNode.x[2],
            found->x[0], found->x[1], found->x[2],
            sqrt(best_dist), visited);

    /* search many random points in million tree to see average behavior.
       tree size vs avg nodes visited:
       10      ~  7
       100     ~ 16.5
       1000        ~ 25.5
       10000       ~ 32.8
       100000      ~ 38.3
       1000000     ~ 42.6
       10000000    ~ 46.7              */
    int sum = 0, test_runs = 100000;
    for (i = 0; i < test_runs; i++) {
        found = 0;
        visited = 0;
        rand_pt(testNode);
        nearest(root, &testNode, 0, 3, &found, &best_dist);
        sum += visited;
    }
    printf("\n>> Million tree\n"
            "visited %d nodes for %d random findings (%f per lookup)\n",
            sum, test_runs, sum/(double)test_runs);

    // free(million);

    return 0;
}


import copy

boardsize=6
_kmoves = ((2,1), (1,2), (-1,2), (-2,1), (-2,-1), (-1,-2), (1,-2), (2,-1))

def chess2index(chess, boardsize=boardsize):
    'Convert Algebraic chess notation to internal index format'
    chess = chess.strip().lower()
    x = ord(chess[0]) - ord('a')
    y = boardsize - int(chess[1:])
    return (x, y)

def boardstring(board, boardsize=boardsize):
    r = range(boardsize)
    lines = ''
    for y in r:
        lines += '\n' + ','.join('%2i' % board[(x,y)] if board[(x,y)] else '  '
                                 for x in r)
    return lines

def knightmoves(board, P, boardsize=boardsize):
    Px, Py = P
    kmoves = set((Px+x, Py+y) for x,y in _kmoves)
    kmoves = set( (x,y)
                  for x,y in kmoves
                  if 0 <= x < boardsize
                     and 0 <= y < boardsize
                     and not board[(x,y)] )
    return kmoves

def accessibility(board, P, boardsize=boardsize):
    access = []
    brd = copy.deepcopy(board)
    for pos in knightmoves(board, P, boardsize=boardsize):
        brd[pos] = -1
        access.append( (len(knightmoves(brd, pos, boardsize=boardsize)), pos) )
        brd[pos] = 0
    return access

def knights_tour(start, boardsize=boardsize, _debug=False):
    board = {(x,y):0 for x in range(boardsize) for y in range(boardsize)}
    move = 1
    P = chess2index(start, boardsize)
    board[P] = move
    move += 1
    if _debug:
        print(boardstring(board, boardsize=boardsize))
    while move <= len(board):
        P = min(accessibility(board, P, boardsize))[1]
        board[P] = move
        move += 1
        if _debug:
            print(boardstring(board, boardsize=boardsize))
            input('\n%2i next: ' % move)
    return board

if __name__ == '__main__':
    while 1:
        boardsize = int(input('\nboardsize: '))
        if boardsize < 5:
            continue
        start = input('Start position: ')
        board = knights_tour(start, boardsize)
        print(boardstring(board, boardsize=boardsize))


#include <algorithm>
#include <array>
#include <cmath>
#include <iostream>
#include <random>
#include <vector>

/**
 * Class for representing a point. coordinate_type must be a numeric type.
 */
template<typename coordinate_type, size_t dimensions>
class point {
public:
    point(std::array<coordinate_type, dimensions> c) : coords_(c) {}
    point(std::initializer_list<coordinate_type> list) {
        size_t n = std::min(dimensions, list.size());
        std::copy_n(list.begin(), n, coords_.begin());
    }
    /**
     * Returns the coordinate in the given dimension.
     *
     * @param index dimension index (zero based)
     * @return coordinate in the given dimension
     */
    coordinate_type get(size_t index) const {
        return coords_[index];
    }
    /**
     * Returns the distance squared from this point to another
     * point.
     *
     * @param pt another point
     * @return distance squared from this point to the other point
     */
    double distance(const point& pt) const {
        double dist = 0;
        for (size_t i = 0; i < dimensions; ++i) {
            double d = get(i) - pt.get(i);
            dist += d * d;
        }
        return dist;
    }
private:
    std::array<coordinate_type, dimensions> coords_;
};

template<typename coordinate_type, size_t dimensions>
std::ostream& operator<<(std::ostream& out, const point<coordinate_type, dimensions>& pt) {
    out << '(';
    for (size_t i = 0; i < dimensions; ++i) {
        if (i > 0)
            out << ", ";
        out << pt.get(i);
    }
    out << ')';
    return out;
}

/**
 * C++ k-d tree implementation, based on the C version at rosettacode.org.
 */
template<typename coordinate_type, size_t dimensions>
class kdtree {
public:
    typedef point<coordinate_type, dimensions> point_type;
private:
    struct node {
        node(const point_type& pt) : point_(pt), left_(nullptr), right_(nullptr) {}
        coordinate_type get(size_t index) const {
            return point_.get(index);
        }
        double distance(const point_type& pt) const {
            return point_.distance(pt);
        }
        point_type point_;
        node* left_;
        node* right_;
    };
    node* root_ = nullptr;
    node* best_ = nullptr;
    double best_dist_ = 0;
    size_t visited_ = 0;
    std::vector<node> nodes_;

    struct node_cmp {
        node_cmp(size_t index) : index_(index) {}
        bool operator()(const node& n1, const node& n2) const {
            return n1.point_.get(index_) < n2.point_.get(index_);
        }
        size_t index_;
    };

    node* make_tree(size_t begin, size_t end, size_t index) {
        if (end <= begin)
            return nullptr;
        size_t n = begin + (end - begin)/2;
        auto i = nodes_.begin();
        std::nth_element(i + begin, i + n, i + end, node_cmp(index));
        index = (index + 1) % dimensions;
        nodes_[n].left_ = make_tree(begin, n, index);
        nodes_[n].right_ = make_tree(n + 1, end, index);
        return &nodes_[n];
    }

    void nearest(node* root, const point_type& point, size_t index) {
        if (root == nullptr)
            return;
        ++visited_;
        double d = root->distance(point);
        if (best_ == nullptr || d < best_dist_) {
            best_dist_ = d;
            best_ = root;
        }
        if (best_dist_ == 0)
            return;
        double dx = root->get(index) - point.get(index);
        index = (index + 1) % dimensions;
        nearest(dx > 0 ? root->left_ : root->right_, point, index);
        if (dx * dx >= best_dist_)
            return;
        nearest(dx > 0 ? root->right_ : root->left_, point, index);
    }
public:
    kdtree(const kdtree&) = delete;
    kdtree& operator=(const kdtree&) = delete;
    /**
     * Constructor taking a pair of iterators. Adds each
     * point in the range [begin, end) to the tree.
     *
     * @param begin start of range
     * @param end end of range
     */
    template<typename iterator>
    kdtree(iterator begin, iterator end) : nodes_(begin, end) {
        root_ = make_tree(0, nodes_.size(), 0);
    }

    /**
     * Constructor taking a function object that generates
     * points. The function object will be called n times
     * to populate the tree.
     *
     * @param f function that returns a point
     * @param n number of points to add
     */
    template<typename func>
    kdtree(func&& f, size_t n) {
        nodes_.reserve(n);
        for (size_t i = 0; i < n; ++i)
            nodes_.push_back(f());
        root_ = make_tree(0, nodes_.size(), 0);
    }

    /**
     * Returns true if the tree is empty, false otherwise.
     */
    bool empty() const { return nodes_.empty(); }

    /**
     * Returns the number of nodes visited by the last call
     * to nearest().
     */
    size_t visited() const { return visited_; }

    /**
     * Returns the distance between the input point and return value
     * from the last call to nearest().
     */
    double distance() const { return std::sqrt(best_dist_); }

    /**
     * Finds the nearest point in the tree to the given point.
     * It is not valid to call this function if the tree is empty.
     *
     * @param pt a point
     * @return the nearest point in the tree to the given point
     */
    const point_type& nearest(const point_type& pt) {
        if (root_ == nullptr)
            throw std::logic_error("tree is empty");
        best_ = nullptr;
        visited_ = 0;
        best_dist_ = 0;
        nearest(root_, pt, 0);
        return best_->point_;
    }
};

void test_wikipedia() {
    typedef point<int, 2> point2d;
    typedef kdtree<int, 2> tree2d;

    point2d points[] = { { 2, 3 }, { 5, 4 }, { 9, 6 }, { 4, 7 }, { 8, 1 }, { 7, 2 } };

    tree2d tree(std::begin(points), std::end(points));
    point2d n = tree.nearest({ 9, 2 });

    std::cout << "Wikipedia example data:\n";
    std::cout << "nearest point: " << n << '\n';
    std::cout << "distance: " << tree.distance() << '\n';
    std::cout << "nodes visited: " << tree.visited() << '\n';
}

typedef point<double, 3> point3d;
typedef kdtree<double, 3> tree3d;

struct random_point_generator {
    random_point_generator(double min, double max)
        : engine_(std::random_device()()), distribution_(min, max) {}

    point3d operator()() {
        double x = distribution_(engine_);
        double y = distribution_(engine_);
        double z = distribution_(engine_);
        return point3d({x, y, z});
    }

    std::mt19937 engine_;
    std::uniform_real_distribution<double> distribution_;
};

void test_random(size_t count) {
    random_point_generator rpg(0, 1);
    tree3d tree(rpg, count);
    point3d pt(rpg());
    point3d n = tree.nearest(pt);

    std::cout << "Random data (" << count << " points):\n";
    std::cout << "point: " << pt << '\n';
    std::cout << "nearest point: " << n << '\n';
    std::cout << "distance: " << tree.distance() << '\n';
    std::cout << "nodes visited: " << tree.visited() << '\n';
}

int main() {
    try {
        test_wikipedia();
        std::cout << '\n';
        test_random(1000);
        std::cout << '\n';
        test_random(1000000);
    } catch (const std::exception& e) {
        std::cerr << e.what() << '\n';
    }
    return 0;
}


#!/usr/bin/Rscript

# M x N Chess Board.
M = 8; N = 8; board = matrix(0, nrow = M, ncol = N)

# Get/Set value on a board position.
getboard = function (position)    { board[position[1], position[2]] }
setboard = function (position, x) { board[position[1], position[2]] <<- x }

# (Relative) Hops of a Knight.
hops = cbind(c(-2, -1), c(-1, -2), c(+1, -2), c(+2, -1),
             c(+2, +1), c(+1, +2), c(-1, +2), c(-2, +1))

# Validate a move.
valid = function (move) {
    all(1 <= move & move <= c(M, N)) && (getboard(move) == 0)
}

# Moves possible from a given position.
explore = function (position) {
    moves = position + hops
    cbind(moves[, apply(moves, 2, valid)])
}

# Possible moves sorted according to their Wornsdorff cost.
candidates = function (position) {
    moves = explore(position)

    # No candidate moves available.
    if (ncol(moves) == 0) { return(moves) }

    wcosts = apply(moves, 2, function (position) { ncol(explore(position)) })
    cbind(moves[, order(wcosts)])
}

# Recursive function for touring the chess board.
knightTour = function (position, moveN) {

    # Tour Complete.
    if (moveN > (M * N)) {
        print(board)
        quit()
    }

    # Available moves.
    moves = candidates(position)

    # None possible. Backtrack.
    if (ncol(moves) == 0) { return() }

    # Make a move, and continue the tour.
    apply(moves, 2, function (position) {
                        setboard(position, moveN)
                        knightTour(position, moveN + 1)
                        setboard(position, 0)
                    })
}

# User Input: Starting position (in algebraic notation).
square = commandArgs(trailingOnly = TRUE)

# Convert into board co-ordinates.
row      = M + 1 - as.integer(substr(square, 2, 2))
ascii    = function (ch) { as.integer(charToRaw(ch)) }
col      = 1 + ascii(substr(square, 1, 1)) - ascii('a')
position = c(row, col)

# Begin tour.
setboard(position, 1); knightTour(position, 2)


(in-package cl-user)

(defvar *random-target*
  (list (float (/ (random 1000) 100))
        (float (/ (random 1000) 100))
        (float (/ (random 1000) 100))))

(defun distance (n target &key (semi nil))
  "distance node to target:
returns squared euclidean distance, or squared semi distance if option set"
  (if semi
      (expt (- (nth (first n) (second n))
               (nth (first n) target))
            2)
      (reduce #'+
              (mapcar (lambda (x y) (* (- x y) (- x y)))
                      (second n)
                      target))))

(defun target< (n target)
  "returns true if target is to its left in axis dim"
  (< (nth (first n) target)
     (nth (first n) (second n))))

(defun next-node (n target &key (opposite nil))
  "return the next child when nn searching, return opposing child if option
oppose set"
  (if (or (and (target< n target) (not opposite))
          (and (not (target< n target)) opposite))
      (third n)
      (fourth n)))

(defun make-kdtree (axis data dims)
  "a kdtree is a binary tree where nodes are:
terminal: (axis data-point),  or
branch:   (axis split-point (left-kdtree) (right-kdtree))"
  (cond ((null data) nil)
        ((eql (length data) 1)          ; singleton?
         (list axis (first data)))      ; terminal node
        ;; else branch node:
        ;; #pts=odd  splits list into 2 even parts with sp in middle
        ;; #pts=even splits list into 2 uneven parts with shorter length first (but never nil)
        (t
         (let ((sd (sort (copy-list data)
                         #'<
                         :key (lambda (x) (nth axis x)))) ; sort the axis ordinates
               (sp (truncate (length data) 2)) ; get mid pt
               (nxta (mod (1+ axis) dims)))
           (list axis
                 (nth sp sd)
                 (make-kdtree nxta
                              (subseq sd 0 sp)
                              dims)
                 (make-kdtree nxta
                              (subseq sd (1+ sp))
                              dims))))))

(defun visit-kdtree (kdt &key (node-function nil))
  "depth first visit all nodes in kdtree and optionally apply a function to
each node visited"
  (when kdt
    (when node-function (funcall node-function kdt))
    (visit-kdtree (third kdt) :node-function node-function)
    (visit-kdtree (fourth kdt) :node-function node-function)))

(defun count-nodes (kdt)
  "count of the terminal nodes"
  (cond ((null kdt) 0)
        ((= (length kdt) 2) 1)
        (t (+ 1
              (count-nodes (third kdt))
              (count-nodes (fourth kdt))))))

(defvar *hits*)

(defun nn-kdtree (kdt node-stack target)
  "nearest neighbour search"
  (when kdt
    ;; stage 1 - find the 'closest' terminal node using insertion logic
    (let ((best (do ((node kdt (next-node node target)))
                    ((not (next-node node target))
                     (incf *hits*)
                     node)              ; return first best est.
                  (push node node-stack)
                  (incf *hits*))))
      ;; stage 2 - unwind the path, at each node if node is closer then make it best
      (do ((node (pop node-stack) (pop node-stack)))
          ((null node) best)         ; return nearest pt
        ;; iteration: update best if node is closer
        (when (< (distance node target) (distance best target))
          (setf best node))
        ;; venture down opposing side if split point is inside HS
        (let ((opposing-best
                (if (< (distance node target :semi t) (distance best target))
                    (nn-kdtree (next-node node target :opposite t)
                               (list)
                               target)
                    nil)))              ; otherwise ignore this subtree
          (when (and opposing-best
                     (< (distance opposing-best target) (distance best target)))
            (setf best opposing-best)))))))

(defun process (data target
                &key (render nil)
                &aux (dims (length target)))
  "process one set of data & optionally display tree"
  (let* ((*hits* 0)
         (kdt (make-kdtree 0 data dims))
         (nn (nn-kdtree kdt (list) target)))
    (when render
      (visit-kdtree kdt
                    :node-function
                    (lambda (n)
                      (format t
                              "~A node: axis:~A point: ~A target:~A semi-distance-sqd:~A euclidean-distance-sqd:~A~%"
                              (if (not (next-node n target))
                                  "TERMINAL"
                                  "BRANCH")
                              (first n)
                              (second n)
                              target
                              (distance n target :semi t)
                              (distance n target)))))
    (format t "~%NN to ~A is ~A, distance ~A [tree has ~A nodes, ~A were visited.]~%"
            target
            (second nn)
            (sqrt (distance nn target))
            (count-nodes kdt)
            *hits*)))

(defun main ()
  ;; TASK 1 - nn search small set of 2D points
  (process '((2 3) (5 4) (9 6) (4 7) (8 1) (7 2))
           '(9 2)
           :render t)

  ;; TASK 2 - nn search 1000 coordinate points in 3D space
  (process (let ((ll (list)))
             (dotimes (i 10)
               (dotimes (j 10)
                 (dotimes (k 10)
                   (push (list i j k) ll))))
             ll)
           *random-target*))


#lang racket
(define N 8)
(define nexts ; construct the graph
  (let ([ds (for*/list ([x 2] [x* '(+1 -1)] [y* '(+1 -1)])
              (cons (* x* (+ 1 x)) (* y* (- 2 x))))])
    (for*/vector ([i N] [j N])
      (filter values (for/list ([d ds])
                       (let ([i (+ i (car d))] [j (+ j (cdr d))])
                         (and (< -1 i N) (< -1 j N) (+ j (* N i)))))))))
(define (tour x y)
  (define xy (+ x (* N y)))
  (let loop ([seen (list xy)] [ns (vector-ref nexts xy)] [n (sub1 (* N N))])
    (if (zero? n) (reverse seen)
        (for/or ([next (sort (map (λ(n) (cons n (remq* seen (vector-ref nexts n)))) ns)
                             < #:key length #:cache-keys? #t)])
          (loop (cons (car next) seen) (cdr next) (sub1 n))))))
(define (draw tour)
  (define v (make-vector (* N N)))
  (for ([n tour] [i (in-naturals 1)]) (vector-set! v n i))
  (for ([i N])
    (displayln (string-join (for/list ([j (in-range i (* N N) N)])
                              (~a (vector-ref v j) #:width 2 #:align 'right))
                            " "))))
(draw (tour (random N) (random N)))


JMP PrintChar ; jump to the label "PrintChar" where a routine to print a letter to the screen is located.


// Implmentation following pseudocode from
// "An introductory tutorial on kd-trees" by Andrew W. Moore,
// Carnegie Mellon University, PDF accessed from:
// http://www.autonlab.org/autonweb/14665

import std.typecons, std.math, std.algorithm, std.random, std.range,
       std.traits, core.memory;

/// k-dimensional point.
struct Point(size_t k, F) if (isFloatingPoint!F) {
    F[k] data;
    alias data this; // Kills DMD std.algorithm.swap inlining.
                     // Define opIndexAssign and opIndex for dmd.
    enum size_t length = k;

    /// Square of the euclidean distance.
    double sqd(in ref Point!(k, F) q) const pure nothrow @nogc {
        double sum = 0;
        foreach (immutable dim, immutable pCoord; data)
            sum += (pCoord - q[dim]) ^^ 2;
        return sum;
    }
}

// Following field names in the paper.
// rangeElt would be whatever data is associated with the Point.
// We don't bother with it for this example.
struct KdNode(size_t k, F) {
    Point!(k, F) domElt;
    immutable int split;
    typeof(this)* left, right;
}

struct Orthotope(size_t k, F) { /// k-dimensional rectangle.
    Point!(k, F) min, max;
}

struct KdTree(size_t k, F) {
    KdNode!(k, F)* n;
    Orthotope!(k, F) bounds;

    // Constructs a KdTree from a list of points, also associating the
    // bounds of the tree. The bounds could be computed of course, but
    // in this example we know them already. The algorithm is table
    // 6.3 in the paper.
    this(Point!(k, F)[] pts, in Orthotope!(k, F) bounds_) pure {
        static KdNode!(k, F)* nk2(size_t split)(Point!(k, F)[] exset)
        pure {
            if (exset.empty)
                return null;
            if (exset.length == 1)
                return new KdNode!(k, F)(exset[0], split, null, null);

            // Pivot choosing procedure. We find median, then find
            // largest index of points with median value. This
            // satisfies the inequalities of steps 6 and 7 in the
            // algorithm.
            auto m = exset.length / 2;
            topN!((p, q) => p[split] < q[split])(exset, m);
            immutable d = exset[m];
            while (m+1 < exset.length && exset[m+1][split] == d[split])
                m++;

            enum nextSplit = (split + 1) % d.length;//cycle coordinates
            return new KdNode!(k, F)(d, split,
                                     nk2!nextSplit(exset[0 .. m]),
                                     nk2!nextSplit(exset[m + 1 .. $]));
        }

        this.n = nk2!0(pts);
        this.bounds = bounds_;
    }
}

/**
Find nearest neighbor. Return values are:
  nearest neighbor--the ooint within the tree that is nearest p.
  square of the distance to that point.
  a count of the nodes visited in the search.
*/
auto findNearest(size_t k, F)(KdTree!(k, F) t, in Point!(k, F) p)
pure nothrow @nogc {
    // Algorithm is table 6.4 from the paper, with the addition of
    // counting the number nodes visited.
    static Tuple!(Point!(k, F), "nearest",
                  F, "distSqd",
                  int, "nodesVisited")
           nn(KdNode!(k, F)* kd, in Point!(k, F) target,
              Orthotope!(k, F) hr, F maxDistSqd) pure nothrow @nogc {
        if (kd == null)
            return typeof(return)(Point!(k, F)(), F.infinity, 0);

        int nodesVisited = 1;
        immutable s = kd.split;
        auto pivot = kd.domElt;
        auto leftHr = hr;
        auto rightHr = hr;
        leftHr.max[s] = pivot[s];
        rightHr.min[s] = pivot[s];

        KdNode!(k, F)* nearerKd, furtherKd;
        Orthotope!(k, F) nearerHr, furtherHr;
        if (target[s] <= pivot[s]) {
            //nearerKd, nearerHr = kd.left, leftHr;
            //furtherKd, furtherHr = kd.right, rightHr;
            nearerKd = kd.left;
            nearerHr = leftHr;
            furtherKd = kd.right;
            furtherHr = rightHr;
        } else {
            //nearerKd, nearerHr = kd.right, rightHr;
            //furtherKd, furtherHr = kd.left, leftHr;
            nearerKd = kd.right;
            nearerHr = rightHr;
            furtherKd = kd.left;
            furtherHr = leftHr;
        }

        auto n1 = nn(nearerKd, target, nearerHr, maxDistSqd);
        auto nearest = n1.nearest;
        auto distSqd = n1.distSqd;
        nodesVisited += n1.nodesVisited;

        if (distSqd < maxDistSqd)
            maxDistSqd = distSqd;
        auto d = (pivot[s] - target[s]) ^^ 2;
        if (d > maxDistSqd)
            return typeof(return)(nearest, distSqd, nodesVisited);
        d = pivot.sqd(target);
        if (d < distSqd) {
            nearest = pivot;
            distSqd = d;
            maxDistSqd = distSqd;
        }

        immutable n2 = nn(furtherKd, target, furtherHr, maxDistSqd);
        nodesVisited += n2.nodesVisited;
        if (n2.distSqd < distSqd) {
            nearest = n2.nearest;
            distSqd = n2.distSqd;
        }

        return typeof(return)(nearest, distSqd, nodesVisited);
    }

    return nn(t.n, p, t.bounds, F.infinity);
}

void showNearest(size_t k, F)(in string heading, KdTree!(k, F) kd,
                              in Point!(k, F) p) {
    import std.stdio: writeln;
    writeln(heading, ":");
    writeln("Point:            ", p);
    immutable n = kd.findNearest(p);
    writeln("Nearest neighbor: ", n.nearest);
    writeln("Distance:         ", sqrt(n.distSqd));
    writeln("Nodes visited:    ", n.nodesVisited, "\n");
}

void main() {
    static Point!(k, F) randomPoint(size_t k, F)() {
        typeof(return) result;
        foreach (immutable i; 0 .. k)
            result[i] = uniform(F(0), F(1));
        return result;
    }

    static Point!(k, F)[] randomPoints(size_t k, F)(in size_t n) {
        return n.iota.map!(_ => randomPoint!(k, F)).array;
    }

    import std.stdio, std.conv, std.datetime, std.typetuple;
    rndGen.seed(1); // For repeatable outputs.

    alias D2 = TypeTuple!(2, double);
    alias P = Point!D2;
    auto kd1 = KdTree!D2([P([2, 3]), P([5, 4]), P([9, 6]),
                          P([4, 7]), P([8, 1]), P([7, 2])],
                         Orthotope!D2(P([0, 0]), P([10, 10])));
    showNearest("Wikipedia example data", kd1, P([9, 2]));

    enum int N = 400_000;
    alias F3 = TypeTuple!(3, float);
    alias Q = Point!F3;
    StopWatch sw;
    GC.disable;
    sw.start;
    auto kd2 = KdTree!F3(randomPoints!F3(N),
                         Orthotope!F3(Q([0, 0, 0]), Q([1, 1, 1])));
    sw.stop;
    GC.enable;
    showNearest(text("k-d tree with ", N,
                     " random 3D ", F3[1].stringof,
                     " points (construction time: ",
                     sw.peek.msecs, " ms)"), kd2, randomPoint!F3);

    sw.reset;
    sw.start;
    enum int M = 10_000;
    size_t visited = 0;
    foreach (immutable _; 0 .. M) {
        immutable n = kd2.findNearest(randomPoint!F3);
        visited += n.nodesVisited;
    }
    sw.stop;

    writefln("Visited an average of %0.2f nodes on %d searches " ~
             "in %d ms.", visited / double(M), M, sw.peek.msecs);
}


my @board;

my $I = 8;
my $J = 8;
my $F = $I*$J > 99 ?? "%3d" !! "%2d";

# Choose starting position - may be passed in on command line; if
# not, choose random square.
my ($i, $j);

if my $sq = shift @*ARGS {
  die "$*PROGRAM_NAME: illegal start square '$sq'\n" unless ($i, $j) = from_algebraic($sq);
}
else {
  ($i, $j) = (^$I).pick, (^$J).pick;
}

# Move sequence
my @moves = ();

for 1 .. $I * $J -> $move {
  # Record current move
  push @moves, to_algebraic($i,$j);
  # @board[$i] //= [];	 # (uncomment if autoviv is broken)
  @board[$i][$j] = $move;

  # Find move with the smallest degree
  my @min = (9);
  for possible_moves($i,$j) -> @target {
      my ($ni, $nj) = @target;
      my $next = possible_moves($ni,$nj);
      @min = $next, $ni, $nj if $next < @min[0];
  }

  # And make it
  ($i, $j) = @min[1,2];
}

# Print the move list
for @moves.kv -> $i, $m {
    print ',', $i %% 16 ?? "\n" !! " " if $i;
    print $m;
}
say "\n";

# And the board, with move numbers
for ^$I -> $i {
  for ^$J -> $j {
    # Assumes (1) ANSI sequences work, and (2) output
    # is light text on a dark background.
    print "\e[7m" if $i % 2 == $j % 2;
    printf $F, @board[$i][$j];
    print "\e[0m";
  }
  print "\n";
}

# Find the list of positions the knight can move to from the given square
sub possible_moves($i,$j) {
  grep -> [$ni, $nj] { $ni ~~ ^$I and $nj ~~ ^$J and !@board[$ni][$nj] },
    [$i-2,$j-1], [$i-2,$j+1], [$i-1,$j-2], [$i-1,$j+2],
    [$i+1,$j-2], [$i+1,$j+2], [$i+2,$j-1], [$i+2,$j+1];
}

# Return the algebraic name of the square identified by the coordinates
# i=rank, 0=black's home row; j=file, 0=white's queen's rook
sub to_algebraic($i,$j) {
    chr(ord('a') + $j) ~ ($I - $i);
}

# Return the coordinates matching the given algebraic name
sub from_algebraic($square where /^ (<[a..z]>) (\d+) $/) {
   $I - $1, ord(~$0) - ord('a');
}


In addition, for nearby subroutines, BSR can be used in place of JSR to save data. There is also BRA (branch always) for unconditional local jumping, which the original 6502 didn't have.


JCXZ bar
foo:
LOOP foo      ;subtract 1 from CX, and if CX is still nonzero jump back to foo
bar:


procedure Goto_Test is
begin

   Stuff;
   goto The_Mother_Ship; -- You can do this if you really must!
   Stuff;
   if condition then
      Stuff;
   <<Jail>>
      Stuff;
   end if;
   Stuff;

   -- Ada does not permit any of the following
   goto Jail;
   goto The_Sewer;
   goto The_Morgue;

   Stuff;
   case condition is
      when Arm1 =>
         Stuff;
         goto The_Gutter; -- Cant do this either
         Stuff;
      when Arm2 =>
         Stuff;
      <<The_Gutter>>
         Stuff;
      <<The_Sewer>>
         Stuff;
   end case;

   Stuff;
   for I in Something'Range loop
      Stuff;
   <<The_Morgue>>
      if You_Are_In_Trouble then
         goto The_Mother_Ship;
         -- This is the usual use of a goto.
      end if;
      Stuff;
   end loop;

   Stuff;
<<The_Mother_Ship>>
   Stuff;

end Goto_Test;


MOV PC,R0   ;loads the program counter with the value in R0. (Any register can be used for this)
LDR PC,[R0] ;loads the program counter with the 32-bit value at the memory location specified by R0


; Define a function.
function()
{
	MsgBox, Start
	gosub jump

	free:
	MsgBox, Success
}

; Call the function.
function()
goto next
return

jump:
MsgBox, Suspended
return

next:
Loop, 3
{
	gosub jump
}
return

/*
Output (in Message Box):

Start
Suspended
Success
Suspended
Suspended
Suspended

*/


// Implmentation following pseudocode from "An intoductory tutorial on kd-trees"
// by Andrew W. Moore, Carnegie Mellon University, PDF accessed from
// http://www.autonlab.org/autonweb/14665
package main

import (
    "fmt"
    "math"
    "math/rand"
    "sort"
    "time"
)

// point is a k-dimensional point.
type point []float64

// sqd returns the square of the euclidean distance.
func (p point) sqd(q point) float64 {
    var sum float64
    for dim, pCoord := range p {
        d := pCoord - q[dim]
        sum += d * d
    }
    return sum
}

// kdNode following field names in the paper.
// rangeElt would be whatever data is associated with the point.  we don't
// bother with it for this example.
type kdNode struct {
    domElt      point
    split       int
    left, right *kdNode
}

type kdTree struct {
    n      *kdNode
    bounds hyperRect
}

type hyperRect struct {
    min, max point
}

// Go slices are reference objects.  The data must be copied if you want
// to modify one without modifying the original.
func (hr hyperRect) copy() hyperRect {
    return hyperRect{append(point{}, hr.min...), append(point{}, hr.max...)}
}

// newKd constructs a kdTree from a list of points, also associating the
// bounds of the tree.  The bounds could be computed of course, but in this
// example we know them already.  The algorithm is table 6.3 in the paper.
func newKd(pts []point, bounds hyperRect) kdTree {
    var nk2 func([]point, int) *kdNode
    nk2 = func(exset []point, split int) *kdNode {
        if len(exset) == 0 {
            return nil
        }
        // pivot choosing procedure.  we find median, then find largest
        // index of points with median value.  this satisfies the
        // inequalities of steps 6 and 7 in the algorithm.
        sort.Sort(part{exset, split})
        m := len(exset) / 2
        d := exset[m]
        for m+1 < len(exset) && exset[m+1][split] == d[split] {
            m++
        }
        // next split
        s2 := split + 1
        if s2 == len(d) {
            s2 = 0
        }
        return &kdNode{d, split, nk2(exset[:m], s2), nk2(exset[m+1:], s2)}
    }
    return kdTree{nk2(pts, 0), bounds}
}

// a container type used for sorting.  it holds the points to sort and
// the dimension to use for the sort key.
type part struct {
    pts   []point
    dPart int
}

// satisfy sort.Interface
func (p part) Len() int { return len(p.pts) }
func (p part) Less(i, j int) bool {
    return p.pts[i][p.dPart] < p.pts[j][p.dPart]
}
func (p part) Swap(i, j int) { p.pts[i], p.pts[j] = p.pts[j], p.pts[i] }

// nearest.  find nearest neighbor.  return values are:
//    nearest neighbor--the point within the tree that is nearest p.
//    square of the distance to that point.
//    a count of the nodes visited in the search.
func (t kdTree) nearest(p point) (best point, bestSqd float64, nv int) {
    return nn(t.n, p, t.bounds, math.Inf(1))
}

// algorithm is table 6.4 from the paper, with the addition of counting
// the number nodes visited.
func nn(kd *kdNode, target point, hr hyperRect,
    maxDistSqd float64) (nearest point, distSqd float64, nodesVisited int) {
    if kd == nil {
        return nil, math.Inf(1), 0
    }
    nodesVisited++
    s := kd.split
    pivot := kd.domElt
    leftHr := hr.copy()
    rightHr := hr.copy()
    leftHr.max[s] = pivot[s]
    rightHr.min[s] = pivot[s]
    targetInLeft := target[s] <= pivot[s]
    var nearerKd, furtherKd *kdNode
    var nearerHr, furtherHr hyperRect
    if targetInLeft {
        nearerKd, nearerHr = kd.left, leftHr
        furtherKd, furtherHr = kd.right, rightHr
    } else {
        nearerKd, nearerHr = kd.right, rightHr
        furtherKd, furtherHr = kd.left, leftHr
    }
    var nv int
    nearest, distSqd, nv = nn(nearerKd, target, nearerHr, maxDistSqd)
    nodesVisited += nv
    if distSqd < maxDistSqd {
        maxDistSqd = distSqd
    }
    d := pivot[s] - target[s]
    d *= d
    if d > maxDistSqd {
        return
    }
    if d = pivot.sqd(target); d < distSqd {
        nearest = pivot
        distSqd = d
        maxDistSqd = distSqd
    }
    tempNearest, tempSqd, nv := nn(furtherKd, target, furtherHr, maxDistSqd)
    nodesVisited += nv
    if tempSqd < distSqd {
        nearest = tempNearest
        distSqd = tempSqd
    }
    return
}

func main() {
    rand.Seed(time.Now().Unix())
    kd := newKd([]point{{2, 3}, {5, 4}, {9, 6}, {4, 7}, {8, 1}, {7, 2}},
        hyperRect{point{0, 0}, point{10, 10}})
    showNearest("WP example data", kd, point{9, 2})
    kd = newKd(randomPts(3, 1000), hyperRect{point{0, 0, 0}, point{1, 1, 1}})
    showNearest("1000 random 3d points", kd, randomPt(3))
}

func randomPt(dim int) point {
    p := make(point, dim)
    for d := range p {
        p[d] = rand.Float64()
    }
    return p
}

func randomPts(dim, n int) []point {
    p := make([]point, n)
    for i := range p {
        p[i] = randomPt(dim)
    }
    return p
}

func showNearest(heading string, kd kdTree, p point) {
    fmt.Println()
    fmt.Println(heading)
    fmt.Println("point:           ", p)
    nn, ssq, nv := kd.nearest(p)
    fmt.Println("nearest neighbor:", nn)
    fmt.Println("distance:        ", math.Sqrt(ssq))
    fmt.Println("nodes visited:   ", nv)
}


#-----------------------------------------------------------------------
#
#     Find Knight’s Tours.
#
#     Using Warnsdorff’s heuristic, find multiple solutions.
#     Optionally accept only closed tours.
#
#     This program is migrated from my implementation for ATS/Postiats.
#     Arrays with dimension 1:64 take the place of stack frames.
#
#     Compile with, for instance:
#
#         ratfor77 knights_tour.r > knights_tour.f
#         gfortran -O2 -g -std=legacy -o knights_tour knights_tour.f
#
#     or
#
#         ratfor77 knights_tour.r > knights_tour.f
#         f2c knights_tour.f
#         cc -O -o knights_tour knights_tour.c -lf2c
#
#     Usage examples:
#
#         One tour starting at a1, either open or closed:
#
#            echo "a1 1 F" | ./knights_tour
#
#         No more than 2000 closed tours starting at c5:
#
#            echo "c5 2000 T" | ./knights_tour
#
#-----------------------------------------------------------------------

program ktour
implicit none

character*2 alg
integer i, j
integer mxtour
logical closed

read (*,*) alg, mxtour, closed
call alg2ij (alg, i, j)
call explor (i, j, mxtour, closed)

end

#-----------------------------------------------------------------------

subroutine explor (istart, jstart, mxtour, closed)
implicit none

# Explore the space of 'Warnsdorffian' knight’s paths, looking for
# and printing complete tours.

integer istart, jstart    # The starting position.
integer mxtour            # The maximum number of tours to print.
logical closed            # Closed tours only?

integer board(1:8,1:8)
integer imove(1:8,1:64)
integer jmove(1:8,1:64)
integer nmove(1:64)
integer n
integer itours
logical goodmv
logical isclos

itours = 0
call initbd (board)
n = 1
nmove(1) = 8
imove(8, 1) = istart
jmove(8, 1) = jstart

while (itours < mxtour && n != 0) {
  if (nmove(n) == 9) {
    n = n - 1
    if (n != 0) {
      call unmove (board, imove, jmove, nmove, n)
      nmove(n) = nmove(n) + 1
    }
  } else if (goodmv (imove, nmove, n)) {
    call mkmove (board, imove, jmove, nmove, n)
    if (n == 64) {
      if (.not. closed) {
        itours = itours + 1
        call prnt (board, itours)
      } else if (isclos (board)) {
        itours = itours + 1
        call prnt (board, itours)
      }
      call unmove (board, imove, jmove, nmove, n)
      nmove(n) = 9
    } else if (n == 63) {
      call possib (board, n, imove, jmove, nmove)
      n = n + 1
      nmove(n) = 1
    } else {
      call nxtmov (board, n, imove, jmove, nmove)
      n = n + 1
      nmove(n) = 1
    }
  } else {
    nmove(n) = nmove(n) + 1
  }
}

end

#-----------------------------------------------------------------------

subroutine initbd (board)
implicit none

# Initialize a chessboard with empty squares.

integer board(1:8,1:8)

integer i, j

do j = 1, 8 {
  do i = 1, 8 {
    board(i, j) = -1
  }
}

end

#-----------------------------------------------------------------------

subroutine mkmove (board, imove, jmove, nmove, n)
implicit none

# Fill a square with a move number.

integer board(1:8, 1:8)
integer imove(1:8, 1:64)
integer jmove(1:8, 1:64)
integer nmove(1:64)
integer n

board(imove(nmove(n), n), jmove(nmove(n), n)) = n

end

#-----------------------------------------------------------------------

subroutine unmove (board, imove, jmove, nmove, n)
implicit none

# Unmake a mkmove.

integer board(1:8, 1:8)
integer imove(1:8, 1:64)
integer jmove(1:8, 1:64)
integer nmove(1:64)
integer n

board(imove(nmove(n), n), jmove(nmove(n), n)) = -1

end

#-----------------------------------------------------------------------

function goodmv (imove, nmove, n)
implicit none

logical goodmv
integer imove(1:8, 1:64)
integer nmove(1:64)
integer n

goodmv = (imove(nmove(n), n) != -1)

end

#-----------------------------------------------------------------------

subroutine prnt (board, itours)
implicit none

# Print a knight's tour.

integer board(1:8,1:8)
integer itours

10000 format (1X)

# The following plethora of format statements seemed a simple way to
# get this working with f2c. (For gfortran, the 'I0' format
# sufficed.)
10010 format (1X, "Tour number ", I1)
10020 format (1X, "Tour number ", I2)
10030 format (1X, "Tour number ", I3)
10040 format (1X, "Tour number ", I4)
10050 format (1X, "Tour number ", I5)
10060 format (1X, "Tour number ", I6)
10070 format (1X, "Tour number ", I20)

if (itours < 10) {
  write (*, 10010) itours
} else if (itours < 100) {
  write (*, 10020) itours
} else if (itours < 1000) {
  write (*, 10030) itours
} else if (itours < 10000) {
  write (*, 10040) itours
} else if (itours < 100000) {
  write (*, 10050) itours
} else if (itours < 1000000) {
  write (*, 10060) itours
} else {
  write (*, 10070) itours
}
call prntmv (board)
call prntbd (board)
write (*, 10000)

end

#-----------------------------------------------------------------------

subroutine prntbd (board)
implicit none

# Print a chessboard with the move number in each square.

integer board(1:8,1:8)

integer i, j

10000 format (1X, "    ", 8("+----"), "+")
10010 format (1X, I2, " ", 8(" | ", I2), " | ")
10020 format (1X, "   ", 8("    ", A1))

do i = 8, 1, -1 {
  write (*, 10000)
  write (*, 10010) i, (board(i, j), j = 1, 8)
}
write (*, 10000)
write (*, 10020) 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'

end

#-----------------------------------------------------------------------

subroutine prntmv (board)
implicit none

# Print the moves of a knight's path, in algebraic notation.

integer board(1:8,1:8)

integer ipos(1:64)
integer jpos(1:64)
integer numpos
character*2 alg(1:64)
integer columns(1:8)
integer k
integer m

character*72 lines(1:8)

10000 format (1X, A)

call bd2pos (board, ipos, jpos, numpos)

# Convert the positions to algebraic notation.
do k = 1, numpos {
  call ij2alg (ipos(k), jpos(k), alg(k))
}

# Fill lines with algebraic notations.
do m = 1, 8 {
  columns(m) = 1
}
m = 1
do k = 1, numpos {
   lines(m)(columns(m) : columns(m) + 1) = alg(k)(1:2)
   columns(m) = columns(m) + 2
   if (k != numpos) {
     lines(m)(columns(m) : columns(m) + 3) = " -> "
     columns(m) = columns(m) + 4
   } else if (numpos == 64 &&                                    _
              ((abs (ipos(numpos) - ipos(1)) == 2                _
                 && abs (jpos(numpos) - jpos(1)) == 1)           _
               || ((abs (ipos(numpos) - ipos(1)) == 1            _
                     && abs (jpos(numpos) - jpos(1)) == 2)))) {
      lines(m)(columns(m) : columns(m) + 8) = " -> cycle"
      columns(m) = columns(m) + 9
   }
   if (mod (k, 8) == 0) m = m + 1
}

# Print the lines that have stuff in them.
do m = 1, 8 {
  if (columns(m) != 1) {
    write (*, 10000) lines(m)(1 : columns(m) - 1)
  }
}

end

#-----------------------------------------------------------------------

function isclos (board)
implicit none

# Is a board a closed tour?

logical isclos
integer board(1:8,1:8)
integer ipos(1:64)        # The i-positions in order.
integer jpos(1:64)        # The j-positions in order.
integer numpos            # The number of positions so far.

call bd2pos (board, ipos, jpos, numpos)

isclos = (numpos == 64 &&                                   _
          ((abs (ipos(numpos) - ipos(1)) == 2               _
             && abs (jpos(numpos) - jpos(1)) == 1)          _
            || ((abs (ipos(numpos) - ipos(1)) == 1          _
                  && abs (jpos(numpos) - jpos(1)) == 2))))

end

#-----------------------------------------------------------------------

subroutine bd2pos (board, ipos, jpos, numpos)
implicit none

# Convert from a board to a list of board positions.

integer board(1:8,1:8)
integer ipos(1:64)        # The i-positions in order.
integer jpos(1:64)        # The j-positions in order.
integer numpos            # The number of positions so far.

integer i, j

numpos = 0
do i = 1, 8 {
  do j = 1, 8 {
    if (board(i, j) != -1) {
      numpos = max (board(i, j), numpos)
      ipos(board(i, j)) = i
      jpos(board(i, j)) = j
    }
  }
}

end

#-----------------------------------------------------------------------

subroutine nxtmov (board, n, imove, jmove, nmove)
implicit none

# Find possible next moves. Prune and sort the moves according to
# Warnsdorff's heuristic, keeping only those that have the minimum
# number of legal following moves.

integer board(1:8,1:8)
integer n
integer imove(1:8,1:64)
integer jmove(1:8,1:64)
integer nmove(1:64)

integer w1, w2, w3, w4, w5, w6, w7, w8
integer w
integer n1
integer pickw

call possib (board, n, imove, jmove, nmove)

n1 = n + 1
nmove(n1) = 1
call countf (board, n1, imove, jmove, nmove, w1)
nmove(n1) = 2
call countf (board, n1, imove, jmove, nmove, w2)
nmove(n1) = 3
call countf (board, n1, imove, jmove, nmove, w3)
nmove(n1) = 4
call countf (board, n1, imove, jmove, nmove, w4)
nmove(n1) = 5
call countf (board, n1, imove, jmove, nmove, w5)
nmove(n1) = 6
call countf (board, n1, imove, jmove, nmove, w6)
nmove(n1) = 7
call countf (board, n1, imove, jmove, nmove, w7)
nmove(n1) = 8
call countf (board, n1, imove, jmove, nmove, w8)

w = pickw (w1, w2, w3, w4, w5, w6, w7, w8)

if (w == 0) {
  call disabl (imove(1, n1), jmove(1, n1))
  call disabl (imove(2, n1), jmove(2, n1))
  call disabl (imove(3, n1), jmove(3, n1))
  call disabl (imove(4, n1), jmove(4, n1))
  call disabl (imove(5, n1), jmove(5, n1))
  call disabl (imove(6, n1), jmove(6, n1))
  call disabl (imove(7, n1), jmove(7, n1))
  call disabl (imove(8, n1), jmove(8, n1))
} else {
  if (w != w1) call disabl (imove(1, n1), jmove(1, n1))
  if (w != w2) call disabl (imove(2, n1), jmove(2, n1))
  if (w != w3) call disabl (imove(3, n1), jmove(3, n1))
  if (w != w4) call disabl (imove(4, n1), jmove(4, n1))
  if (w != w5) call disabl (imove(5, n1), jmove(5, n1))
  if (w != w6) call disabl (imove(6, n1), jmove(6, n1))
  if (w != w7) call disabl (imove(7, n1), jmove(7, n1))
  if (w != w8) call disabl (imove(8, n1), jmove(8, n1))
}

end

#-----------------------------------------------------------------------

subroutine countf (board, n, imove, jmove, nmove, w)
implicit none

# Count the number of moves possible after an nth move.

integer board(1:8,1:8)
integer n
integer imove(1:8,1:64)
integer jmove(1:8,1:64)
integer nmove(1:64)
integer w

logical goodmv
integer n1

if (goodmv (imove, nmove, n)) {
  call mkmove (board, imove, jmove, nmove, n)
  call possib (board, n, imove, jmove, nmove)
  n1 = n + 1
  w = 0
  if (imove(1, n1) != -1) w = w + 1
  if (imove(2, n1) != -1) w = w + 1
  if (imove(3, n1) != -1) w = w + 1
  if (imove(4, n1) != -1) w = w + 1
  if (imove(5, n1) != -1) w = w + 1
  if (imove(6, n1) != -1) w = w + 1
  if (imove(7, n1) != -1) w = w + 1
  if (imove(8, n1) != -1) w = w + 1
  call unmove (board, imove, jmove, nmove, n)
} else {
  # The nth move itself is impossible.
  w = 0
}

end

#-----------------------------------------------------------------------

function pickw (w1, w2, w3, w4, w5, w6, w7, w8)
implicit none

# From w1..w8, pick out the least nonzero value (or zero if they all
# equal zero).

integer pickw
integer w1, w2, w3, w4, w5, w6, w7, w8

integer w
integer pickw1

w = 0
w = pickw1 (w, w1)
w = pickw1 (w, w2)
w = pickw1 (w, w3)
w = pickw1 (w, w4)
w = pickw1 (w, w5)
w = pickw1 (w, w6)
w = pickw1 (w, w7)
w = pickw1 (w, w8)

pickw = w

end

#-----------------------------------------------------------------------

function pickw1 (u, v)
implicit none

# A small function used by pickw.

integer pickw1
integer u, v

if (v == 0) {
  pickw1 = u
} else if (u == 0) {
  pickw1 = v
} else {
  pickw1 = min (u, v)
}

end

#-----------------------------------------------------------------------

subroutine possib (board, n, imove, jmove, nmove)
implicit none

# Find moves that are possible from an nth-move position.

integer board(1:8,1:8)
integer n
integer imove(1:8,1:64)
integer jmove(1:8,1:64)
integer nmove(1:64)

integer i, j
integer n1

i = imove(nmove(n), n)
j = jmove(nmove(n), n)
n1 = n + 1
call trymov (board, i + 1, j + 2, imove(1, n1), jmove(1, n1))
call trymov (board, i + 2, j + 1, imove(2, n1), jmove(2, n1))
call trymov (board, i + 1, j - 2, imove(3, n1), jmove(3, n1))
call trymov (board, i + 2, j - 1, imove(4, n1), jmove(4, n1))
call trymov (board, i - 1, j + 2, imove(5, n1), jmove(5, n1))
call trymov (board, i - 2, j + 1, imove(6, n1), jmove(6, n1))
call trymov (board, i - 1, j - 2, imove(7, n1), jmove(7, n1))
call trymov (board, i - 2, j - 1, imove(8, n1), jmove(8, n1))

end

#-----------------------------------------------------------------------

subroutine trymov (board, i, j, imove, jmove)
implicit none

# Try a move to square (i, j).

integer board(1:8,1:8)
integer i, j
integer imove, jmove

call disabl (imove, jmove)
if (1 <= i && i <= 8 && 1 <= j && j <= 8) {
  if (board(i,j) == -1) {
    call enable (i, j, imove, jmove)
  }
}

end

#-----------------------------------------------------------------------

subroutine enable (i, j, imove, jmove)
implicit none

# Enable a potential move.

integer i, j
integer imove, jmove

imove = i
jmove = j

end

#-----------------------------------------------------------------------

subroutine disabl (imove, jmove)
implicit none

# Disable a potential move.

integer imove, jmove

imove = -1
jmove = -1

end

#-----------------------------------------------------------------------

subroutine alg2ij (alg, i, j)
implicit none

# Convert, for instance, 'c5' to i=3,j=5.

character*2 alg
integer i, j

if (alg(1:1) == 'a') j = 1
if (alg(1:1) == 'b') j = 2
if (alg(1:1) == 'c') j = 3
if (alg(1:1) == 'd') j = 4
if (alg(1:1) == 'e') j = 5
if (alg(1:1) == 'f') j = 6
if (alg(1:1) == 'g') j = 7
if (alg(1:1) == 'h') j = 8

if (alg(2:2) == '1') i = 1
if (alg(2:2) == '2') i = 2
if (alg(2:2) == '3') i = 3
if (alg(2:2) == '4') i = 4
if (alg(2:2) == '5') i = 5
if (alg(2:2) == '6') i = 6
if (alg(2:2) == '7') i = 7
if (alg(2:2) == '8') i = 8

end

#-----------------------------------------------------------------------

subroutine ij2alg (i, j, alg)
implicit none

# Convert, for instance, i=3,j=5 to 'c5'.

integer i, j
character*2 alg

character alg1
character alg2

if (j == 1) alg1 = 'a'
if (j == 2) alg1 = 'b'
if (j == 3) alg1 = 'c'
if (j == 4) alg1 = 'd'
if (j == 5) alg1 = 'e'
if (j == 6) alg1 = 'f'
if (j == 7) alg1 = 'g'
if (j == 8) alg1 = 'h'

if (i == 1) alg2 = '1'
if (i == 2) alg2 = '2'
if (i == 3) alg2 = '3'
if (i == 4) alg2 = '4'
if (i == 5) alg2 = '5'
if (i == 6) alg2 = '6'
if (i == 7) alg2 = '7'
if (i == 8) alg2 = '8'

alg(1:1) = alg1
alg(2:2) = alg2

end

#-----------------------------------------------------------------------


10 GOTO 100: REM jump to a specific line
20 RUN 200: REM start the program running from a specific line


print "First line."
gosub sub1
print "Fifth line."
goto Ending

sub1:
print "Second line."
gosub sub2
print "Fourth line."
return

Ending:
print "We're just about done..."
goto Finished

sub2:
print "Third line."
return

Finished:
print "... with goto and gosub, thankfully."
end


	if (x > 0) goto positive;
	else goto negative;

positive:
	printf("pos\n"); goto both;

negative:
	printf("neg\n");

both:
	...


if (x > 0) goto positive;
else goto negative;

positive:
    Console.WriteLine("pos\n"); goto both;

negative:
    Console.WriteLine("neg\n");

both:
    ...


import System.Random
import Data.List (sortBy, genericLength, minimumBy)
import Data.Ord (comparing)

-- A finite list of dimensional accessors tell a KDTree how to get a
-- Euclidean dimensional value 'b' out of an arbitrary datum 'a'.
type DimensionalAccessors a b = [a -> b]

-- A binary tree structure of 'a'.
data Tree a = Node a (Tree a) (Tree a)
            | Empty

instance Show a => Show (Tree a) where
  show Empty = "Empty"
  show (Node value left right) =
    "(" ++ show value ++ " " ++ show left ++ " " ++ show right ++ ")"

-- A k-d tree structure of 'a' with Euclidean dimensions of 'b'.
data KDTree a b = KDTree (DimensionalAccessors a b) (Tree a)

instance Show a => Show (KDTree a b) where
  show (KDTree _ tree) = "KDTree " ++ show tree

-- The squared Euclidean distance formula.
sqrDist :: Num b => DimensionalAccessors a b -> a -> a -> b
sqrDist dims a b = sum $ map square $ zipWith (-) a' b'
  where
    a' = map ($ a) dims
    b' = map ($ b) dims

square :: Num a => a -> a
square = (^ 2)

-- Insert a value into a k-d tree.
insert :: Ord b => KDTree a b -> a -> KDTree a b
insert (KDTree dims tree) value = KDTree dims $ ins (cycle dims) tree
  where
    ins _      Empty                   = Node value Empty Empty
    ins (d:ds) (Node split left right) =
      if d value < d split
      then Node split (ins ds left) right
      else Node split left (ins ds right)

-- Produce an empty k-d tree.
empty :: DimensionalAccessors a b -> KDTree a b
empty dims = KDTree dims Empty

-- Produce a k-d tree with one value.
singleton :: Ord b => DimensionalAccessors a b -> a -> KDTree a b
singleton dims value = insert (empty dims) value

-- Create a k-d tree from a list of values using the median-finding algorithm.
fromList :: Ord b => DimensionalAccessors a b -> [a] -> KDTree a b
fromList dims values = KDTree dims $ fList (cycle dims) values
  where
    fList _      []     = Empty
    fList (d:ds) values =
      let sorted          = sortBy (comparing d) values
          (lower, higher) = splitAt (genericLength sorted `div` 2) sorted
      in case higher of
        []          -> Empty
        median:rest -> Node median (fList ds lower) (fList ds rest)

-- Create a k-d tree from a list of values by repeatedly inserting the values
-- into a tree. Faster than median-finding, but can create unbalanced trees.
fromListLinear :: Ord b => DimensionalAccessors a b -> [a] -> KDTree a b
fromListLinear dims values = foldl insert (empty dims) values

-- Given a k-d tree, find the nearest value to a given value.
-- Also report how many nodes were visited.
nearest :: (Ord b, Num b, Integral c) => KDTree a b -> a -> (Maybe a, c)
nearest (KDTree dims tree) value = near (cycle dims) tree
  where
    dist = sqrDist dims
    -- If we have an empty tree, then return nothing.
    near _      Empty                    = (Nothing, 1)
    -- We hit a leaf node, so it is the current best.
    near _      (Node split Empty Empty) = (Just split, 1)
    near (d:ds) (Node split left right)  =
      -- Move down the tree in the fashion of insertion.
      let dimdist x y    = square (d x - d y)
          splitDist      = dist value split
          hyperPlaneDist = dimdist value split
          bestLeft       = near ds left
          bestRight      = near ds right
          -- maybeThisBest is the node of the side of the split where the value
          -- resides, and maybeOtherBest is the node on the other side of the split.
          ((maybeThisBest, thisCount), (maybeOtherBest, otherCount)) =
            if d value < d split
            then (bestLeft, bestRight)
            else (bestRight, bestLeft)
      in case maybeThisBest of
        Nothing    ->
          -- From the search point (in this case), the hypersphere radius to
          -- the split node is always >= the hyperplane distance, so we will
          -- always check the other side.
          let count = 1 + thisCount + otherCount
          in case maybeOtherBest of
            -- We are currently at a leaf node, so this is the only choice.
            -- It is not strictly necessary to take care of this case
            -- because of the above pattern matching in near.
            Nothing         -> (Just split, count)
            -- We have a node on the other side, so compare
            -- it to the split point to see which is closer.
            Just otherBest ->
              if dist value otherBest < splitDist
              then (maybeOtherBest, count)
              else (Just split, count)

        Just thisBest ->
          let thisBestDist = dist value thisBest
              best         =
                -- Determine which is the closer node of this side.
                if splitDist < thisBestDist
                then split
                else thisBest
              bestDist     = dist value best
          in
            if bestDist < hyperPlaneDist
            -- If the distance to the best node is less than the distance
            -- to the splitting hyperplane, then the current best node is the
            -- only choice.
            then (Just best, 1 + thisCount)
            -- There is a chance that a node on the other side is closer
            -- than the current best.
            else
              let count = 1 + thisCount + otherCount
              in case maybeOtherBest of
                Nothing        -> (Just best, count)
                Just otherBest ->
                  if bestDist < dist value otherBest
                  then (Just best, count)
                  else (maybeOtherBest, count)

-- Dimensional accessors for a 2-tuple
tuple2D :: [(a, a) -> a]
tuple2D = [fst, snd]

-- Dimensional accessors for a 3-tuple
tuple3D :: [(a, a, a) -> a]
tuple3D = [d1, d2, d3]
  where
    d1 (a, _, _) = a
    d2 (_, b, _) = b
    d3 (_, _, c) = c

-- Random 3-tuple generation
instance (Random a, Random b, Random c) => Random (a, b, c) where
  random gen =
    let (vA, genA) = random gen
        (vB, genB) = random genA
        (vC, genC) = random genB
    in ((vA, vB, vC), genC)

  randomR ((lA, lB, lC), (hA, hB, hC)) gen =
    let (vA, genA) = randomR (lA, hA) gen
        (vB, genB) = randomR (lB, hB) genA
        (vC, genC) = randomR (lC, hC) genB
    in ((vA, vB, vC), genC)

printResults :: (Show a, Show b, Show c, Floating c) =>
                a -> (Maybe a, b) -> DimensionalAccessors a c -> IO ()
printResults point result dims = do
  let (nearest, visited) = result
  case nearest of
    Nothing    -> putStrLn "Could not find nearest."
    Just value -> do
      let dist = sqrt $ sqrDist dims point value
      putStrLn $ "Point:    " ++ show point
      putStrLn $ "Nearest:  " ++ show value
      putStrLn $ "Distance: " ++ show dist
      putStrLn $ "Visited:  " ++ show visited
      putStrLn ""

-- Naive nearest search used to confirm results.
linearNearest :: (Ord b, Num b) => DimensionalAccessors a b -> a -> [a] -> Maybe a
linearNearest _    _     [] = Nothing
linearNearest dims value xs = Just $ minimumBy (comparing $ sqrDist dims value) xs

main :: IO ()
main = do
  let wikiValues :: [(Double, Double)]
      wikiValues  = [(2, 3), (5, 4), (9, 6), (4, 7), (8, 1), (7, 2)]
      wikiTree    = fromList tuple2D wikiValues
      wikiSearch  = (9, 2)
      wikiNearest = nearest wikiTree wikiSearch
  putStrLn "Wikipedia example:"
  printResults wikiSearch wikiNearest tuple2D

  let stdGen                = mkStdGen 0
      randRange :: ((Double, Double, Double), (Double, Double, Double))
      randRange             = ((0, 0, 0), (1000, 1000, 1000))
      (randSearch, stdGenB) = randomR randRange stdGen
      randValues            = take 1000 $ randomRs randRange stdGenB
      randTree              = fromList tuple3D randValues
      randNearest           = nearest randTree randSearch
      randNearestLinear     = linearNearest tuple3D randSearch randValues
  putStrLn "1000 random 3D points on the range of [0, 1000):"
  printResults randSearch randNearest tuple3D
  putStrLn "Confirm naive nearest:"
  print randNearestLinear


/*REXX program solves the  knight's tour  problem   for a  (general)   NxN   chessboard.*/
parse arg  N  sRank sFile .                      /*obtain optional arguments from the CL*/
if     N=='' |     N==","  then     N=8          /*No boardsize specified?  Use default.*/
if sRank=='' | sRank==","  then sRank=N          /*No starting rank given?   "      "   */
if sFile=='' | sFile==","  then sFile=1          /* "     "    file   "      "      "   */
NN=N**2;            NxN='a ' N"x"N ' chessboard' /*file [↓]           [↓]   r=rank      */
@.=;    do r=1  for N;  do f=1  for N;  @.r.f=.;  end  /*f*/;   end  /*r*/
beg= '-1-'                                       /*[↑]  create an empty  NxN chessboard.*/
               Kr =  '2  1 -1 -2  -2 -1  1  2'   /*the legal "rank"  moves for a knight.*/
               Kf =  '1  2  2  1  -1 -2 -2 -1'   /* "    "   "file"    "    "  "    "   */
kr.M=words(Kr)                                   /*number of possible moves for a Knight*/
parse var  Kr  Kr.1 Kr.2 Kr.3 Kr.4 Kr.5 Kr.6 Kr.7 Kr.8   /*parse the legal moves by hand*/
parse var  Kf  Kf.1 Kf.2 Kf.3 Kf.4 Kf.5 Kf.6 Kf.7 Kf.8   /*  "    "    "     "    "   " */
@.sRank.sFile= beg                               /*the knight's starting position.      */
@kt= "knight's tour"                             /*a handy-dandy literal for the  SAYs. */
if \move(2, sRank, sFile)  &  \(N==1)  then say 'No'   @kt   "solution for"         NxN'.'
                                       else say 'A solution for the'   @kt   "on"   NxN':'
!=left('', 9 * (n<18) )                          /*used for indentation of chessboard.  */
_=substr(copies("┼───",N),2);   say;   say  ! translate('┌'_"┐", '┬', "┼")   /*a square.*/
                                                 /* [↓]  build a display for chessboard.*/
     do   r=N  for N  by -1;    if r\==N  then say ! '├'_"┤";        [email protected].
       do f=1  for N; [email protected].r.f;  if ?==NN  then ?='end';  L=L'│'center(?, 3)  /*is "end"?*/
       end   /*f*/                               /*done with   rank   of the chessboard.*/
     say ! translate(L'│', , .)                  /*display a     "     "  "       "     */
     end     /*r*/                               /*19x19 chessboard can be shown 80 cols*/

say  !  translate('└'_"┘", '┴', "┼")             /*show the last rank of the chessboard.*/
exit                                             /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
move: procedure expose @. Kr. Kf. NN;    parse arg #,rank,file  /*obtain move,rank,file.*/
         do t=1  for Kr.M;   nr=rank+Kr.t;       nf=file+Kf.t   /*position of the knight*/
         if @.nr.nf==.  then do;                 @.nr.nf=#      /*Empty? Knight can move*/
                             if #==NN            then return 1  /*is this the last move?*/
                             if move(#+1,nr,nf)  then return 1  /* "   "   "    "    "  */
                             @.nr.nf=.                          /*undo the above move.  */
                             end                                /*try different move.   */
         end   /*t*/                                            /* [↑]  all moves tried.*/
      return 0                                                  /*tour is not possible. */


#include <iostream>
#include <utility>

using namespace std;

int main(void)
{
    cout << "Find a solution to i = 2 * j - 7\n";
    pair<int, int> answer;
    for(int i = 0; true; i++)
    {
        for(int j = 0; j < i; j++)
        {
            if( i == 2 * j - 7)
            {
                // use brute force and run until a solution is found
                answer = make_pair(i, j);
                goto loopexit;
            }
        }
    }

loopexit:
    cout << answer.first << " = 2 * " << answer.second << " - 7\n\n";

    // jumping out of nested loops is the main usage of goto in
    // C++.  goto can be used in other places but there is usually
    // a better construct.  goto is not allowed to jump across
    // initialized variables which limits where it can be used.
    // this is case where C++ is more restrictive than C.

    goto spagetti;

    int k;
    k = 9;  // this is assignment, can be jumped over

    /* The line below won't compile because a goto is not allowed
     * to jump over an initialized value.
    int j = 9;
    */

spagetti:

    cout << "k = " << k << "\n";  // k was never initialized, accessing it is undefined behavior

}


IDENTIFICATION DIVISION.
PROGRAM-ID. JUMPS-PROGRAM.
* Nobody writes like this, of course; but...
PROCEDURE DIVISION.
* You can jump anywhere you like.
START-PARAGRAPH.
    GO TO AN-ARBITRARY-PARAGRAPH.
YET-ANOTHER-PARAGRAPH.
    ALTER START-PARAGRAPH TO PROCEED TO A-PARAGRAPH-SOMEWHERE.
* That's right, folks: we don't just have GO TOs, we have GO TOs whose
* destinations can be changed at will, from anywhere in the program,
* at run time.
    GO TO START-PARAGRAPH.
* But bear in mind: once you get there, the GO TO no longer goes to
* where it says it goes to.
A-PARAGRAPH-SOMEWHERE.
    DISPLAY 'Never heard of him.'
    STOP RUN.
SOME-OTHER-PARAGRAPH.
* You think that's bad? You ain't seen nothing.
    GO TO YET-ANOTHER-PARAGRAPH.
AN-ARBITRARY-PARAGRAPH.
    DISPLAY 'Edsger who now?'
    GO TO SOME-OTHER-PARAGRAPH.


coclass 'kdnode'
  create=:3 :0
    Axis=: ({:$y)|<.2^.#y
    Mask=: Axis~:i.{:$y
    if. 3>#y do.
      Leaf=:1
      Points=: y
    else.
      Leaf=:0
      data=. y /: Axis|."1 y
      n=. <.-:#data
      Points=: ,:n{data
      Left=: conew&'kdnode' n{.data
      Right=: conew&'kdnode' (1+n)}.data
    end.
  )

  distance=: +/&.:*:@:-"1

  nearest=:3 :0
    _ 0 nearest y
  :
    n=.' ',~":N_base_=:N_base_+1
    dists=. Points distance y
    ndx=. (i. <./) dists
    nearest=. ndx { Points
    range=. ndx { dists
    if. Leaf do.
      range;nearest return.
    else.
      d0=. x <. range
      p0=. nearest
      if. d0=0 do. 0;y return. end.
      if. 0={./:Axis|."1 y,Points do.
        'dist pnt'=.d0 nearest__Left y
        if. dist > d0 do.
          d0;p0 return.
        end.
        if. dist < d0 do.
          if. dist > (Mask#pnt) distance Mask#,Points do.
            'dist2 pnt2'=. d0 nearest__Right y
            if. dist2 < dist do. dist2;pnt2 return. end.
          end.
        end.
      else.
        'dist pnt'=. d0 nearest__Right y
        if. dist > d0 do.
          d0;p0 return.
        end.
        if. dist < d0 do.
          if. dist > (Mask#pnt) distance Mask#,Points do.
            'dist2 pnt2'=. d0 nearest__Left y
            if. dist2 < dist do. dist2;pnt2 return. end.
          end.
        end.
      end.
    end.
    dist;pnt return.
  )

coclass 'kdtree'
  create=:3 :0
    root=: conew&'kdnode' y
  )
  nearest=:3 :0
    N_base_=:0
    'dist point'=. nearest__root y
    dist;N_base_;point
  )


import java.util.*;

public class KdTree {
    private int dimensions_;
    private Node root_ = null;
    private Node best_ = null;
    private double bestDistance_ = 0;
    private int visited_ = 0;

    public KdTree(int dimensions, List<Node> nodes) {
        dimensions_ = dimensions;
        root_ = makeTree(nodes, 0, nodes.size(), 0);
    }

    public Node findNearest(Node target) {
        if (root_ == null)
            throw new IllegalStateException("Tree is empty!");
        best_ = null;
        visited_ = 0;
        bestDistance_ = 0;
        nearest(root_, target, 0);
        return best_;
    }

    public int visited() {
        return visited_;
    }

    public double distance() {
        return Math.sqrt(bestDistance_);
    }

    private void nearest(Node root, Node target, int index) {
        if (root == null)
            return;
        ++visited_;
        double d = root.distance(target);
        if (best_ == null || d < bestDistance_) {
            bestDistance_ = d;
            best_ = root;
        }
        if (bestDistance_ == 0)
            return;
        double dx = root.get(index) - target.get(index);
        index = (index + 1) % dimensions_;
        nearest(dx > 0 ? root.left_ : root.right_, target, index);
        if (dx * dx >= bestDistance_)
            return;
        nearest(dx > 0 ? root.right_ : root.left_, target, index);
    }

    private Node makeTree(List<Node> nodes, int begin, int end, int index) {
        if (end <= begin)
            return null;
        int n = begin + (end - begin)/2;
        Node node = QuickSelect.select(nodes, begin, end - 1, n, new NodeComparator(index));
        index = (index + 1) % dimensions_;
        node.left_ = makeTree(nodes, begin, n, index);
        node.right_ = makeTree(nodes, n + 1, end, index);
        return node;
    }

    private static class NodeComparator implements Comparator<Node> {
        private int index_;

        private NodeComparator(int index) {
            index_ = index;
        }
        public int compare(Node n1, Node n2) {
            return Double.compare(n1.get(index_), n2.get(index_));
        }
    }

    public static class Node {
        private double[] coords_;
        private Node left_ = null;
        private Node right_ = null;

        public Node(double[] coords) {
            coords_ = coords;
        }
        public Node(double x, double y) {
            this(new double[]{x, y});
        }
        public Node(double x, double y, double z) {
            this(new double[]{x, y, z});
        }
        double get(int index) {
            return coords_[index];
        }
        double distance(Node node) {
            double dist = 0;
            for (int i = 0; i < coords_.length; ++i) {
                double d = coords_[i] - node.coords_[i];
                dist += d * d;
            }
            return dist;
        }
        public String toString() {
            StringBuilder s = new StringBuilder("(");
            for (int i = 0; i < coords_.length; ++i) {
                if (i > 0)
                    s.append(", ");
                s.append(coords_[i]);
            }
            s.append(')');
            return s.toString();
        }
    }
}


class Board
  Cell = Struct.new(:value, :adj) do
    def self.end=(end_val)
      @@end = end_val
    end

    def try(seq_num)
      self.value = seq_num
      return true  if [email protected]@end
      a = []
      adj.each_with_index do |cell, n|
        a << [wdof(cell.adj)*10+n, cell]  if cell.value.zero?
      end
      a.sort.each {|_, cell| return true  if cell.try(seq_num+1)}
      self.value = 0
      false
    end

    def wdof(adj)
      adj.count {|cell| cell.value.zero?}
    end
  end

  def initialize(rows, cols)
    @rows, @cols = rows, cols
    unless defined? ADJACENT                      # default move (Knight)
      eval("ADJACENT = [[-1,-2],[-2,-1],[-2,1],[-1,2],[1,2],[2,1],[2,-1],[1,-2]]")
    end
    frame = ADJACENT.flatten.map(&:abs).max
    @board = Array.new(rows+frame) do |i|
      Array.new(cols+frame) do |j|
        (i<rows and j<cols) ? Cell.new(0) : nil   # frame (Sentinel value : nil)
      end
    end
    rows.times do |i|
      cols.times do |j|
        @board[i][j].adj = ADJACENT.map{|di,dj| @board[i+di][j+dj]}.compact
      end
    end
    Cell.end = rows * cols
    @format = " %#{(rows * cols).to_s.size}d"
  end

  def solve(sx, sy)
    if (@rows*@cols).odd? and (sx+sy).odd?
      puts "No solution"
    else
      puts (@board[sx][sy].try(1) ? to_s : "No solution")
    end
  end

  def to_s
    (0[email protected]).map do |x|
      (0[email protected]).map{|y| @format % @board[x][y].value}.join
    end
  end
end

def knight_tour(rows=8, cols=rows, sx=rand(rows), sy=rand(cols))
  puts "\nBoard (%d x %d), Start:[%d, %d]" % [rows, cols, sx, sy]
  Board.new(rows, cols).solve(sx, sy)
end

knight_tour(8,8,3,1)

knight_tour(5,5,2,2)

knight_tour(4,9,0,0)

knight_tour(5,5,0,1)

knight_tour(12,12,1,1)


(tagbody
  beginning
    (format t "I am in the beginning~%")
    (sleep 1)
    (go end)
  middle
    (format t "I am in the middle~%")
    (sleep 1)
    (go beginning)
  end
    (format t "I am in the end~%")
    (sleep 1)
    (go middle))


        LDA  goto
        SUB  somewhere
        ADD  somewhereElse
        STA  goto
goto:   JMP  somewhere


$ return  ! ignored since we haven't done a gosub yet
$
$ if p1 .eqs. "" then $ goto main
$ inner:
$ exit
$
$ main:
$ goto label  ! if label hasn't been read yet then DCL will read forward to find label
$ label:
$ write sys$output "after first occurrence of label"
$
$ on control_y then $ goto continue1  ! we will use this to get out of the loop that's coming up
$
$ label:  ! duplicate labels *are* allowed, the most recently read is the one that will be the target
$  write sys$output "after second occurrence of label"
$  wait 0::2  ! since we are in a loop this will slow things down
$  goto label  ! hit ctrl-y to break out
$
$ continue1:  ! the previous "on control_y" remains in force despite having been triggered
$
$ label = "jump"
$ goto 'label  ! target can be a variable; talk about handy
$ jump:
$ write sys$output "after first occurrence of jump"
$
$ first_time = "true"
$ continue_label = "continue2"
$ 'continue_label:  ! even the label can be a variable (but only backwards); talk about handy
$ if first_time then $ goto skip
$ break = "true"
$ return
$
$ skip:
$ first_time = "false"
$
$ on control_y then $ gosub 'continue_label  ! setup a new on control_y to get out the next loop coming up
$
$ break = "false"
$ 'label:
$  write sys$output "after second occurrence of jump"
$  wait 0::2
$  if .not. break then $ goto 'label
$
$ gosub sub1  ! no new scope or parameters
$ label = "sub1"
$ gosub 'label
$
$ call sub4 a1 b2 c3  ! new scope and parameters
$
$ @nl:  ! new scope and parameters in another file but same process
$
$ procedure_filename = f$environment( "procedure " )  ! what is our own filename?
$ @'procedure_filename inner
$
$ exit  ! exiting outermost scope exits the command procedure altogether, i.e. back to shell
$
$ sub1:
$ return
$
$ sub2:
$ goto break  ! structurally disorganized but allowed
$
$ sub3:
$ return
$
$ break:
$ return
$
$ sub4: subroutine
$ exit
$ endsubroutine


ENV["NN_DEBUG"] = true # or change DEBUG = true in NearestNeighbors.jl file

using NearestNeighbors

const data = [[2, 3] [5, 4] [9, 6] [4, 7] [8, 1] [7, 2]]

NearestNeighbors.reset_stats()
const kdtree = KDTree(Float64.(data))
const indexpoint = [9,2]
idx, dist = knn(kdtree, indexpoint, 1)
println("Wikipedia example: The nearest neighbor to $indexpoint is ",
    "$(data[1:2, idx[1]]) at distance $(dist).")
NearestNeighbors.print_stats()

NearestNeighbors.reset_stats()
const cubedis = rand(3, 1000)
const kdcubetree = KDTree(cubedis)
const rand3point = rand(3, 1)
idx, dist = knn(kdcubetree, rand3point, 1)
println("\n\n1000 cube points: The point $rand3point is closest to the point $(cubedis[1:3, idx[1]])",
    " at distance $(dist[1]).")
NearestNeighbors.print_stats()

NearestNeighbors.reset_stats()
const cubedis2 = rand(3, 500000)
const kdcubetree2 = KDTree(cubedis2)
const rand3point2 = rand(3, 1)
idx, dist = knn(kdcubetree2, rand3point2, 1)
println("\n\nExtra: The point $rand3point2 is closest to the point $(cubedis2[1:3, idx[1]]) out of $(size(cubedis2)[2]) points,",
    " at distance $(dist[1]).")
NearestNeighbors.print_stats()


// version 1.1.51

import java.util.Random

typealias Point = DoubleArray

fun Point.sqd(p: Point) = this.zip(p) { a, b -> (a - b) * (a - b) }.sum()

class HyperRect (val min: Point, val max: Point) {
    fun copy() = HyperRect(min.copyOf(), max.copyOf())
}

data class NearestNeighbor(val nearest: Point?, val distSqd: Double, val nodesVisited: Int)

class KdNode(
    val domElt: Point,
    val split: Int,
    var left:  KdNode?,
    var right: KdNode?
)

class KdTree {
    val n: KdNode?
    val bounds: HyperRect

    constructor(pts: MutableList<Point>, bounds: HyperRect) {
        fun nk2(exset: MutableList<Point>, split: Int): KdNode? {
            if (exset.size == 0) return null
            val exset2 = exset.sortedBy { it[split] }
            for (i in 0 until exset.size) exset[i] = exset2[i]
            var m = exset.size / 2
            val d = exset[m]
            while (m + 1 < exset.size && exset[m + 1][split] == d[split]) m++
            var s2 = split + 1
            if (s2 == d.size) s2 = 0
            return KdNode(
                d,
                split,
                nk2(exset.subList(0, m), s2),
                nk2(exset.subList(m + 1, exset.size), s2)
            )
        }
        this.n = nk2(pts, 0)
        this.bounds = bounds
    }

    fun nearest(p: Point) = nn(n, p, bounds, Double.POSITIVE_INFINITY)

    private fun nn(
        kd: KdNode?,
        target: Point,
        hr: HyperRect,
        maxDistSqd: Double
    ): NearestNeighbor {
        if (kd == null) return NearestNeighbor(null, Double.POSITIVE_INFINITY, 0)
        var nodesVisited = 1
        val s = kd.split
        val pivot = kd.domElt
        val leftHr = hr.copy()
        val rightHr = hr.copy()
        leftHr.max[s] = pivot[s]
        rightHr.min[s] = pivot[s]
        val targetInLeft = target[s] <= pivot[s]
        val nearerKd = if (targetInLeft) kd.left else kd.right
        val nearerHr = if (targetInLeft) leftHr else rightHr
        val furtherKd = if (targetInLeft) kd.right else kd.left
        val furtherHr = if (targetInLeft) rightHr else leftHr
        var (nearest, distSqd, nv) = nn(nearerKd, target, nearerHr, maxDistSqd)
        nodesVisited += nv
        var maxDistSqd2 = if (distSqd < maxDistSqd) distSqd else maxDistSqd
        var d = pivot[s] - target[s]
        d *= d
        if (d > maxDistSqd2) return NearestNeighbor(nearest, distSqd, nodesVisited)
        d = pivot.sqd(target)
        if (d < distSqd) {
            nearest = pivot
            distSqd = d
            maxDistSqd2 = distSqd
        }
        val temp = nn(furtherKd, target, furtherHr, maxDistSqd2)
        nodesVisited += temp.nodesVisited
        if (temp.distSqd < distSqd) {
            nearest = temp.nearest
            distSqd = temp.distSqd
        }
        return NearestNeighbor(nearest, distSqd, nodesVisited)
    }
}

val rand = Random()

fun randomPt(dim: Int) = Point(dim) { rand.nextDouble() }

fun randomPts(dim: Int, n: Int) = MutableList<Point>(n) { randomPt(dim) }

fun showNearest(heading: String, kd: KdTree, p: Point) {
    println("$heading:")
    println("Point            : ${p.asList()}")
    val (nn, ssq, nv) = kd.nearest(p)
    println("Nearest neighbor : ${nn?.asList()}")
    println("Distance         : ${Math.sqrt(ssq)}")
    println("Nodes visited    : $nv")
    println()
}

fun main(args: Array<String>) {
    val points = mutableListOf(
        doubleArrayOf(2.0, 3.0),
        doubleArrayOf(5.0, 4.0),
        doubleArrayOf(9.0, 6.0),
        doubleArrayOf(4.0, 7.0),
        doubleArrayOf(8.0, 1.0),
        doubleArrayOf(7.0, 2.0)
    )
    var hr = HyperRect(doubleArrayOf(0.0, 0.0), doubleArrayOf(10.0, 10.0))
    var kd = KdTree(points, hr)
    showNearest("WP example data", kd, doubleArrayOf(9.0, 2.0))

    hr = HyperRect(doubleArrayOf(0.0, 0.0, 0.0), doubleArrayOf(1.0, 1.0, 1.0))
    kd = KdTree(randomPts(3, 1000), hr)
    showNearest("1000 random 3D points", kd, randomPt(3))

    hr = hr.copy()
    kd = KdTree(randomPts(3, 400_000), hr)
    showNearest("400,000 random 3D points", kd, randomPt(3))
}


use std::fmt;

const SIZE: usize = 8;
const MOVES: [(i32, i32); 8] = [
    (2, 1),
    (1, 2),
    (-1, 2),
    (-2, 1),
    (-2, -1),
    (-1, -2),
    (1, -2),
    (2, -1),
];

#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord)]
struct Point {
    x: i32,
    y: i32,
}

impl Point {
    fn mov(&self, &(dx, dy): &(i32, i32)) -> Self {
        Self {
            x: self.x + dx,
            y: self.y + dy,
        }
    }
}

struct Board {
    field: [[i32; SIZE]; SIZE],
}

impl Board {
    fn new() -> Self {
        Self {
            field: [[0; SIZE]; SIZE],
        }
    }

    fn available(&self, p: Point) -> bool {
        0 <= p.x
            && p.x < SIZE as i32
            && 0 <= p.y
            && p.y < SIZE as i32
            && self.field[p.x as usize][p.y as usize] == 0
    }

    // calculate the number of possible moves
    fn count_degree(&self, p: Point) -> i32 {
        let mut count = 0;
        for dir in MOVES.iter() {
            let next = p.mov(dir);
            if self.available(next) {
                count += 1;
            }
        }
        count
    }
}

impl fmt::Display for Board {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        for row in self.field.iter() {
            for x in row.iter() {
                write!(f, "{:3} ", x)?;
            }
            write!(f, "\n")?;
        }
        Ok(())
    }
}

fn knights_tour(x: i32, y: i32) -> Option<Board> {
    let mut board = Board::new();
    let mut p = Point { x: x, y: y };
    let mut step = 1;
    board.field[p.x as usize][p.y as usize] = step;
    step += 1;

    while step <= (SIZE * SIZE) as i32 {
        // choose next square by Warnsdorf's rule
        let mut candidates = vec![];
        for dir in MOVES.iter() {
            let adj = p.mov(dir);
            if board.available(adj) {
                let degree = board.count_degree(adj);
                candidates.push((degree, adj));
            }
        }
        match candidates.iter().min() {
            // move to next square
            Some(&(_, adj)) => p = adj,
            // can't move
            None => return None,
        };
        board.field[p.x as usize][p.y as usize] = step;
        step += 1;
    }
    Some(board)
}

fn main() {
    let (x, y) = (3, 1);
    println!("Board size: {}", SIZE);
    println!("Starting position: ({}, {})", x, y);
    match knights_tour(x, y) {
        Some(b) => print!("{}", b),
        None => println!("Fail!"),
    }
}


example:
    !print "First part"
    yield
    !print "Second part"

local :continue example
!print "Interrupted"
continue


var
  x: Integer = 5;

label
  positive, negative, both;

begin
  if (x > 0) then
    goto positive
  else
    goto negative;

positive:
  writeln('pos');
  goto both;

negative:
  writeln('neg');
both:
  readln;
end.


PROGRAM GOTO_ERR

LABEL 99,100

PROCEDURE P1
   INPUT(I)
   IF I=0 THEN GOTO 99 END IF
END PROCEDURE

PROCEDURE P2
99: PRINT("I'm in procdedure P2")
END PROCEDURE

BEGIN
100:
    INPUT(J)
    IF J=1 THEN GOTO 99 END IF
    IF J<>0 THEN GOTO 100 END IF
END PROGRAM


USING: continuations prettyprint ;

current-continuation short.