Just another update
This commit is contained in:
parent
a25938f123
commit
00a190b0a6
6591 changed files with 94363 additions and 23227 deletions
|
|
@ -1,21 +1,14 @@
|
|||
import std.stdio, std.range, std.string, std.algorithm, std.array,
|
||||
std.typetuple, std.ascii, std.typecons;
|
||||
|
||||
template Range(size_t stop) { // For loop unrolling.
|
||||
static if (stop == 0)
|
||||
alias TypeTuple!() Range;
|
||||
else
|
||||
alias TypeTuple!(Range!(stop - 1), stop - 1) Range;
|
||||
}
|
||||
std.ascii, std.typecons;
|
||||
|
||||
struct Digit {
|
||||
immutable char d;
|
||||
|
||||
this(in char d_) pure nothrow
|
||||
this(in char d_) pure nothrow @safe @nogc
|
||||
in { assert(d_ >= '0' && d_ <= '9'); }
|
||||
body { this.d = d_; }
|
||||
|
||||
this(in int d_) pure nothrow
|
||||
this(in int d_) pure nothrow @safe @nogc
|
||||
in { assert(d_ >= '0' && d_ <= '9'); }
|
||||
body { this.d = cast(char)d_; } // Required cast.
|
||||
|
||||
|
|
@ -34,30 +27,31 @@ pure nothrow {
|
|||
problem[].map!(c => c - '0').copy(grid[]);
|
||||
|
||||
// DMD doesn't inline this function. Performance loss.
|
||||
Tgrid access(in size_t x, in size_t y) nothrow {
|
||||
Tgrid access(in size_t x, in size_t y) nothrow @safe @nogc {
|
||||
return grid[y * sudokuSide + x];
|
||||
}
|
||||
|
||||
// DMD doesn't inline this function. If you want to retain
|
||||
// the same performance as the C++ entry and you use the DMD
|
||||
// compiler then this function must be manually inlined.
|
||||
bool checkValidity(in Tgrid val, in size_t x, in size_t y) nothrow {
|
||||
/*static*/ foreach (immutable i; Range!sudokuSide)
|
||||
bool checkValidity(in Tgrid val, in size_t x, in size_t y)
|
||||
pure nothrow @safe @nogc {
|
||||
/*static*/ foreach (immutable i; staticIota!(0, sudokuSide))
|
||||
if (access(i, y) == val || access(x, i) == val)
|
||||
return false;
|
||||
|
||||
immutable startX = (x / sudokuUnitSide) * sudokuUnitSide;
|
||||
immutable startY = (y / sudokuUnitSide) * sudokuUnitSide;
|
||||
|
||||
/*static*/ foreach (immutable i; Range!sudokuUnitSide)
|
||||
/*static*/ foreach (immutable j; Range!sudokuUnitSide)
|
||||
/*static*/ foreach (immutable i; staticIota!(0, sudokuUnitSide))
|
||||
/*static*/ foreach (immutable j; staticIota!(0, sudokuUnitSide))
|
||||
if (access(startX + j, startY + i) == val)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool canPlaceNumbers(in size_t pos=0) nothrow {
|
||||
bool canPlaceNumbers(in size_t pos=0) nothrow @safe @nogc {
|
||||
if (pos == SudokuTable.length)
|
||||
return true;
|
||||
if (grid[pos] > 0)
|
||||
|
|
@ -87,7 +81,7 @@ pure nothrow {
|
|||
}
|
||||
|
||||
string representSudoku(in ref SudokuTable sudo)
|
||||
pure nothrow out(result) {
|
||||
pure nothrow @safe out(result) {
|
||||
assert(result.countchars("1-9") == sudo[].count!q{a != '0'});
|
||||
assert(result.countchars(".") == sudo[].count!q{a == '0'});
|
||||
} body {
|
||||
34
Task/Sudoku/D/sudoku-2.d
Normal file
34
Task/Sudoku/D/sudoku-2.d
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
import std.stdio, std.algorithm, std.range;
|
||||
|
||||
const(int)[] solve(immutable int[] s) pure nothrow @safe {
|
||||
immutable i = s.countUntil(0);
|
||||
if (i == -1)
|
||||
return s;
|
||||
|
||||
enum B = (int i, int j) => i / 27 ^ j / 27 | (i%9 / 3 ^ j%9 / 3);
|
||||
immutable c = iota(81)
|
||||
.filter!(j => !((i - j) % 9 * (i/9 ^ j/9) * B(i, j)))
|
||||
.map!(j => s[j]).array;
|
||||
|
||||
foreach (immutable v; 1 .. 10)
|
||||
if (!c.canFind(v)) {
|
||||
const r = solve(s[0 .. i] ~ v ~ s[i + 1 .. $]);
|
||||
if (!r.empty)
|
||||
return r;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
void main() {
|
||||
immutable problem = [
|
||||
8, 5, 0, 0, 0, 2, 4, 0, 0,
|
||||
7, 2, 0, 0, 0, 0, 0, 0, 9,
|
||||
0, 0, 4, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 1, 0, 7, 0, 0, 2,
|
||||
3, 0, 5, 0, 0, 0, 9, 0, 0,
|
||||
0, 4, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 8, 0, 0, 7, 0,
|
||||
0, 1, 7, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 3, 6, 0, 4, 0];
|
||||
writefln("%(%s\n%)", problem.solve.chunks(9));
|
||||
}
|
||||
42
Task/Sudoku/D/sudoku-3.d
Normal file
42
Task/Sudoku/D/sudoku-3.d
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
import std.stdio, std.algorithm, std.range, std.typecons;
|
||||
|
||||
Nullable!(const ubyte[81]) solve(in ubyte[81] s) pure nothrow @safe @nogc {
|
||||
immutable i = s[].countUntil(0);
|
||||
if (i == -1)
|
||||
return typeof(return)(s);
|
||||
|
||||
static immutable B = (in int i, in int j) pure nothrow @safe @nogc =>
|
||||
i / 27 ^ j / 27 | (i % 9 / 3 ^ j % 9 / 3);
|
||||
|
||||
ubyte[81] c = void;
|
||||
size_t len = 0;
|
||||
foreach (immutable int j; 0 .. c.length)
|
||||
if (!((i - j) % 9 * (i/9 ^ j/9) * B(i, j)))
|
||||
c[len++] = s[j];
|
||||
|
||||
foreach (immutable ubyte v; 1 .. 10)
|
||||
if (!c[0 .. len].canFind(v)) {
|
||||
ubyte[81] s2 = void;
|
||||
s2[0 .. i] = s[0 .. i];
|
||||
s2[i] = v;
|
||||
s2[i + 1 .. $] = s[i + 1 .. $];
|
||||
const r = solve(s2);
|
||||
if (!r.isNull)
|
||||
return typeof(return)(r);
|
||||
}
|
||||
return typeof(return)();
|
||||
}
|
||||
|
||||
void main() {
|
||||
immutable ubyte[81] problem = [
|
||||
8, 5, 0, 0, 0, 2, 4, 0, 0,
|
||||
7, 2, 0, 0, 0, 0, 0, 0, 9,
|
||||
0, 0, 4, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 1, 0, 7, 0, 0, 2,
|
||||
3, 0, 5, 0, 0, 0, 9, 0, 0,
|
||||
0, 4, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 8, 0, 0, 7, 0,
|
||||
0, 1, 7, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 3, 6, 0, 4, 0];
|
||||
writefln("%(%s\n%)", problem.solve.get[].chunks(9));
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue