tasks a-s
This commit is contained in:
parent
47bf37c096
commit
b83f433714
12433 changed files with 156208 additions and 123 deletions
44
Task/N-queens-problem/D/n-queens-problem-1.d
Normal file
44
Task/N-queens-problem/D/n-queens-problem-1.d
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
import std.stdio;
|
||||
|
||||
enum int SIDE = 8;
|
||||
int[SIDE] board;
|
||||
|
||||
bool unsafe(in int y) nothrow {
|
||||
immutable int x = board[y];
|
||||
foreach (i; 1 .. y + 1) {
|
||||
int t = board[y - i];
|
||||
if ((t == x) || (t == x - i) || (t == x + i))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void showBoard() {
|
||||
static int s = 1;
|
||||
writeln("\nSolution #", s++);
|
||||
foreach (y; 0 .. SIDE) {
|
||||
foreach (x; 0 .. SIDE)
|
||||
write(board[y] == x ? '*' : '.');
|
||||
writeln();
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
int y = 0;
|
||||
board[0] = -1;
|
||||
|
||||
while (y >= 0) {
|
||||
do {
|
||||
board[y]++;
|
||||
} while (board[y] < SIDE && unsafe(y));
|
||||
|
||||
if (board[y] < SIDE) {
|
||||
if (y < (SIDE - 1))
|
||||
board[++y] = -1;
|
||||
else
|
||||
showBoard();
|
||||
} else
|
||||
y--;
|
||||
}
|
||||
}
|
||||
90
Task/N-queens-problem/D/n-queens-problem-2.d
Normal file
90
Task/N-queens-problem/D/n-queens-problem-2.d
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
import std.stdio, std.conv;
|
||||
|
||||
uint nQueens(in uint nn) pure nothrow
|
||||
in {
|
||||
assert(nn > 0 && nn <= 27,
|
||||
"'side' value must be in 1 .. 27.");
|
||||
} body {
|
||||
if (nn < 4)
|
||||
return nn == 1;
|
||||
|
||||
enum uint ulen = uint.sizeof * 8;
|
||||
immutable uint full = uint.max - ((1 << (ulen - nn)) - 1);
|
||||
immutable n = nn - 3;
|
||||
|
||||
uint count;
|
||||
uint[32] l=void, r=void, c=void;
|
||||
uint[33] mm; // mm and mmi are a stack
|
||||
|
||||
// Require second queen to be left of the first queen, so
|
||||
// we ever only test half of the possible solutions. This
|
||||
// is why we can't handle n=1 here.
|
||||
for (uint b0 = 1U << (ulen - n - 3); b0; b0 <<= 1) {
|
||||
for (uint b1 = b0 << 2; b1; b1 <<= 1) {
|
||||
uint d = n;
|
||||
// c: columns occupied by previous queens.
|
||||
c[n] = b0 | b1;
|
||||
// l: columns attacked by left diagonals
|
||||
l[n] = (b0 << 2) | (b1 << 1);
|
||||
// r: by right diagnoals
|
||||
r[n] = (b0 >> 2) | (b1 >> 1);
|
||||
|
||||
// availabe columns on current row
|
||||
uint bits = full & ~(l[n] | r[n] | c[n]);
|
||||
|
||||
uint mmi = 1;
|
||||
mm[mmi] = bits;
|
||||
|
||||
while (bits) {
|
||||
// d: depth, aka row. counting backwards
|
||||
// because !d is often faster than d != n
|
||||
while (d) {
|
||||
// pos is right most nonzero bit
|
||||
immutable uint pos = -(cast(int)bits) & bits;
|
||||
|
||||
// Mark bit used. Only put current bits on
|
||||
// stack if not zero, so backtracking will
|
||||
// skip exhausted rows (because reading stack
|
||||
// variable is slow compared to registers).
|
||||
bits &= ~pos;
|
||||
if (bits) {
|
||||
mm[mmi] = bits | d;
|
||||
mmi++;
|
||||
}
|
||||
|
||||
d--;
|
||||
l[d] = (l[d+1] | pos) << 1;
|
||||
r[d] = (r[d+1] | pos) >> 1;
|
||||
c[d] = c[d+1] | pos;
|
||||
|
||||
bits = full & ~(l[d] | r[d] | c[d]);
|
||||
|
||||
if (!bits)
|
||||
break;
|
||||
if (!d) {
|
||||
count++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Bottom of stack m is a zero'd field acting as
|
||||
// sentinel. When saving to stack, left 27 bits
|
||||
// are the available columns, while right 5 bits
|
||||
// is the depth. Hence solution is limited to size
|
||||
// 27 board -- not that it matters in foreseeable
|
||||
// future.
|
||||
mmi--;
|
||||
bits = mm[mmi];
|
||||
d = bits & 31U;
|
||||
bits &= ~31U;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return count * 2;
|
||||
}
|
||||
|
||||
void main(string[] args) {
|
||||
immutable int side = (args.length >= 2) ? to!int(args[1]) : 8;
|
||||
writefln("N-queens(%d) = %d solutions.", side, nQueens(side));
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue