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

127
Task/Sudoku/D/sudoku-1.d Normal file
View file

@ -0,0 +1,127 @@
import std.stdio, std.range, std.string, std.algorithm, std.array,
std.ascii, std.typecons;
struct Digit {
immutable char d;
this(in char d_) pure nothrow @safe @nogc
in { assert(d_ >= '0' && d_ <= '9'); }
body { this.d = d_; }
this(in int d_) pure nothrow @safe @nogc
in { assert(d_ >= '0' && d_ <= '9'); }
body { this.d = cast(char)d_; } // Required cast.
alias d this;
}
enum size_t sudokuUnitSide = 3;
enum size_t sudokuSide = sudokuUnitSide ^^ 2; // Sudoku grid side.
alias SudokuTable = Digit[sudokuSide ^^ 2];
Nullable!SudokuTable sudokuSolver(in ref SudokuTable problem)
pure nothrow {
alias Tgrid = uint;
Tgrid[SudokuTable.length] grid = void;
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 @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)
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; 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 @safe @nogc {
if (pos == SudokuTable.length)
return true;
if (grid[pos] > 0)
return canPlaceNumbers(pos + 1);
foreach (immutable n; 1 .. sudokuSide + 1)
if (checkValidity(n, pos % sudokuSide, pos / sudokuSide)) {
grid[pos] = n;
if (canPlaceNumbers(pos + 1))
return true;
grid[pos] = 0;
}
return false;
}
if (canPlaceNumbers) {
//return typeof(return)(grid[]
// .map!(c => Digit(c + '0'))
// .array);
immutable SudokuTable result = grid[]
.map!(c => Digit(c + '0'))
.array;
return typeof(return)(result);
} else
return typeof(return)();
}
string representSudoku(in ref SudokuTable sudo)
pure nothrow @safe out(result) {
assert(result.countchars("1-9") == sudo[].count!q{a != '0'});
assert(result.countchars(".") == sudo[].count!q{a == '0'});
} body {
static assert(sudo.length == 81,
"representSudoku works only with a 9x9 Sudoku.");
string result;
foreach (immutable i; 0 .. sudokuSide) {
foreach (immutable j; 0 .. sudokuSide) {
result ~= sudo[i * sudokuSide + j];
result ~= ' ';
if (j == 2 || j == 5)
result ~= "| ";
}
result ~= "\n";
if (i == 2 || i == 5)
result ~= "------+-------+------\n";
}
return result.replace("0", ".");
}
void main() {
enum ValidateCells(string s) = s.map!Digit.array;
immutable SudokuTable problem = ValidateCells!("
850002400
720000009
004000000
000107002
305000900
040000000
000080070
017000000
000036040".removechars(whitespace));
problem.representSudoku.writeln;
immutable solution = problem.sudokuSolver;
if (solution.isNull)
writeln("Unsolvable!");
else
solution.get.representSudoku.writeln;
}

34
Task/Sudoku/D/sudoku-2.d Normal file
View 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
View 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));
}