Data commit

This commit is contained in:
Ingy döt Net 2023-07-01 11:58:00 -04:00
parent 7387c8f97b
commit cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions

View file

@ -0,0 +1,77 @@
import std.stdio, std.algorithm, std.random, std.range,
std.conv, std.typecons, std.typetuple;
int[N][N] knightTour(size_t N=8)(in string start)
in {
assert(start.length >= 2);
} body {
static struct P { int x, y; }
immutable P[8] moves = [P(2,1), P(1,2), P(-1,2), P(-2,1),
P(-2,-1), P(-1,-2), P(1,-2), P(2,-1)];
int[N][N] data;
int[8] sortMoves(in int x, in int y) {
int[2][8] counts;
foreach (immutable i, immutable ref d1; moves) {
int c = 0;
foreach (immutable ref d2; moves) {
immutable p = P(x + d1.x + d2.x, y + d1.y + d2.y);
if (p.x >= 0 && p.x < N && p.y >= 0 && p.y < N &&
data[p.y][p.x] == 0)
c++;
}
counts[i] = [c, i];
}
counts[].randomShuffle; // Shuffle to randomly break ties.
counts[].sort(); // Lexicographic sort.
int[8] result = void;
transversal(counts[], 1).copy(result[]);
return result;
}
immutable p0 = P(start[0] - 'a', N - to!int(start[1 .. $]));
data[p0.y][p0.x] = 1;
Tuple!(int, int, int, int[8])[N * N] order;
order[0] = tuple(p0.x, p0.y, 0, sortMoves(p0.x, p0.y));
int n = 0;
while (n < (N * N - 1)) {
immutable int x = order[n][0];
immutable int y = order[n][1];
bool ok = false;
foreach (immutable i; order[n][2] .. 8) {
immutable P d = moves[order[n][3][i]];
if (x+d.x < 0 || x+d.x >= N || y+d.y < 0 || y+d.y >= N)
continue;
if (data[y + d.y][x + d.x] == 0) {
order[n][2] = i + 1;
n++;
data[y + d.y][x + d.x] = n + 1;
order[n] = tuple(x+d.x,y+d.y,0,sortMoves(x+d.x,y+d.y));
ok = true;
break;
}
}
if (!ok) { // Failed. Backtrack.
data[y][x] = 0;
n--;
}
}
return data;
}
void main() {
foreach (immutable i, side; TypeTuple!(5, 8, 31, 101)) {
immutable form = "%(%" ~ text(side ^^ 2).length.text ~ "d %)";
foreach (ref row; ["c3", "b5", "a1", "a1"][i].knightTour!side)
writefln(form, row);
writeln();
}
}

View file

@ -0,0 +1,27 @@
import std.stdio, std.math, std.algorithm, std.range, std.typecons;
alias Square = Tuple!(int,"x", int,"y");
const(Square)[] knightTour(in Square[] board, in Square[] moves) pure @safe nothrow {
enum findMoves = (in Square sq) pure nothrow @safe =>
cartesianProduct([1, -1, 2, -2], [1, -1, 2, -2])
.filter!(ij => ij[0].abs != ij[1].abs)
.map!(ij => Square(sq.x + ij[0], sq.y + ij[1]))
.filter!(s => board.canFind(s) && !moves.canFind(s));
auto newMoves = findMoves(moves.back);
if (newMoves.empty)
return moves;
//alias warnsdorff = min!(s => findMoves(s).walkLength);
//immutable newSq = newMoves.dropOne.fold!warnsdorff(newMoves.front);
auto pairs = newMoves.map!(s => tuple(findMoves(s).walkLength, s));
immutable newSq = reduce!min(pairs.front, pairs.dropOne)[1];
return board.knightTour(moves ~ newSq);
}
void main(in string[] args) {
enum toSq = (in string xy) => Square(xy[0] - '`', xy[1] - '0');
immutable toAlg = (in Square s) => [dchar(s.x + '`'), dchar(s.y + '0')];
immutable sq = toSq((args.length == 2) ? args[1] : "e5");
const board = iota(1, 9).cartesianProduct(iota(1, 9)).map!Square.array;
writefln("%(%-(%s -> %)\n%)", board.knightTour([sq]).map!toAlg.chunks(8));
}