Just another update
This commit is contained in:
parent
a25938f123
commit
00a190b0a6
6591 changed files with 94363 additions and 23227 deletions
|
|
@ -8,11 +8,11 @@ enum Content { Beer, Coffee, Milk, Tea, Water,
|
|||
enum Test { Drink, Person, Color, Smoke, Pet }
|
||||
enum House { One, Two, Three, Four, Five }
|
||||
|
||||
alias Content[EnumMembers!Test.length][EnumMembers!House.length] TM;
|
||||
alias TM = Content[EnumMembers!Test.length][EnumMembers!House.length];
|
||||
|
||||
bool finalChecks(in ref TM M) pure nothrow {
|
||||
bool finalChecks(in ref TM M) pure nothrow @safe @nogc {
|
||||
int diff(in Content a, in Content b, in Test ca, in Test cb)
|
||||
nothrow {
|
||||
nothrow @safe @nogc {
|
||||
foreach (immutable h1; EnumMembers!House)
|
||||
foreach (immutable h2; EnumMembers!House)
|
||||
if (M[ca][h1] == a && M[cb][h2] == b)
|
||||
|
|
@ -20,16 +20,15 @@ bool finalChecks(in ref TM M) pure nothrow {
|
|||
assert(0); // Useless but required.
|
||||
}
|
||||
|
||||
with (Content) with (Test) { // Braces required (8414).
|
||||
with (Content) with (Test)
|
||||
return abs(diff(Norwegian, Blue, Person, Color)) == 1 &&
|
||||
diff(Green, White, Color, Color) == -1 &&
|
||||
abs(diff(Horse, Dunhill, Pet, Smoke)) == 1 &&
|
||||
abs(diff(Water, Blend, Drink, Smoke)) == 1 &&
|
||||
abs(diff(Blend, Cat, Smoke, Pet)) == 1;
|
||||
}
|
||||
}
|
||||
|
||||
bool constrained(in ref TM M, in Test atest) pure nothrow {
|
||||
bool constrained(in ref TM M, in Test atest) pure nothrow @safe @nogc {
|
||||
with (Content) with (Test) with (House)
|
||||
final switch (atest) {
|
||||
case Drink:
|
||||
|
|
@ -67,7 +66,7 @@ void show(in ref TM M) {
|
|||
writef("%5s: ", h);
|
||||
foreach (immutable t; EnumMembers!Test)
|
||||
writef("%10s ", M[t][h]);
|
||||
writeln();
|
||||
writeln;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,14 @@
|
|||
import std.stdio, std.math, std.traits, std.typetuple, permutations1;
|
||||
import std.stdio, std.math, std.traits, std.typecons, std.typetuple, permutations1;
|
||||
|
||||
uint factorial(in uint n) pure nothrow @nogc @safe
|
||||
in {
|
||||
assert(n <= 12);
|
||||
} body {
|
||||
uint result = 1;
|
||||
foreach (immutable i; 1 .. n + 1)
|
||||
result *= i;
|
||||
return result;
|
||||
}
|
||||
|
||||
enum Number { One, Two, Three, Four, Five }
|
||||
enum Color { Red, Green, Blue, White, Yellow }
|
||||
|
|
@ -7,42 +17,46 @@ enum Smoke { PallMall, Dunhill, Blend, BlueMaster, Prince }
|
|||
enum Pet { Dog, Cat, Zebra, Horse, Bird }
|
||||
enum Nation { British, Swedish, Danish, Norvegian, German }
|
||||
|
||||
bool isPossible(immutable Number[5]* number,
|
||||
immutable Color[5]* color=null,
|
||||
immutable Drink[5]* drink=null,
|
||||
immutable Smoke[5]* smoke=null,
|
||||
immutable Pet[5]* pet=null) pure nothrow {
|
||||
if ((number && (*number)[Nation.Norvegian] != Number.One) ||
|
||||
(color && (*color)[Nation.British] != Color.Red) ||
|
||||
(drink && (*drink)[Nation.Danish] != Drink.Tea) ||
|
||||
(smoke && (*smoke)[Nation.German] != Smoke.Prince) ||
|
||||
(pet && (*pet)[Nation.Swedish] != Pet.Dog))
|
||||
enum size_t M = EnumMembers!Number.length;
|
||||
|
||||
auto nullableRef(T)(ref T item) pure nothrow @nogc {
|
||||
return NullableRef!T(&item);
|
||||
}
|
||||
|
||||
bool isPossible(NullableRef!(immutable Number[M]) number,
|
||||
NullableRef!(immutable Color[M]) color=null,
|
||||
NullableRef!(immutable Drink[M]) drink=null,
|
||||
NullableRef!(immutable Smoke[M]) smoke=null,
|
||||
NullableRef!(immutable Pet[M]) pet=null) pure nothrow @safe @nogc {
|
||||
if ((!number.isNull && number[Nation.Norvegian] != Number.One) ||
|
||||
(!color.isNull && color[Nation.British] != Color.Red) ||
|
||||
(!drink.isNull && drink[Nation.Danish] != Drink.Tea) ||
|
||||
(!smoke.isNull && smoke[Nation.German] != Smoke.Prince) ||
|
||||
(!pet.isNull && pet[Nation.Swedish] != Pet.Dog))
|
||||
return false;
|
||||
|
||||
if (!number || !color || !drink || !smoke || !pet)
|
||||
if (number.isNull || color.isNull || drink.isNull || smoke.isNull ||
|
||||
pet.isNull)
|
||||
return true;
|
||||
|
||||
foreach (immutable i; 0 .. 5) {
|
||||
if (((*color)[i] == Color.Green && (*drink)[i] != Drink.Coffee) ||
|
||||
((*smoke)[i] == Smoke.PallMall && (*pet)[i] != Pet.Bird) ||
|
||||
((*color)[i] == Color.Yellow && (*smoke)[i] != Smoke.Dunhill) ||
|
||||
((*number)[i] == Number.Three && (*drink)[i] != Drink.Milk) ||
|
||||
((*smoke)[i] == Smoke.BlueMaster && (*drink)[i] != Drink.Beer)||
|
||||
((*color)[i] == Color.Blue && (*number)[i] != Number.Two))
|
||||
foreach (immutable i; 0 .. M) {
|
||||
if ((color[i] == Color.Green && drink[i] != Drink.Coffee) ||
|
||||
(smoke[i] == Smoke.PallMall && pet[i] != Pet.Bird) ||
|
||||
(color[i] == Color.Yellow && smoke[i] != Smoke.Dunhill) ||
|
||||
(number[i] == Number.Three && drink[i] != Drink.Milk) ||
|
||||
(smoke[i] == Smoke.BlueMaster && drink[i] != Drink.Beer)||
|
||||
(color[i] == Color.Blue && number[i] != Number.Two))
|
||||
return false;
|
||||
|
||||
foreach (immutable j; 0 .. 5) {
|
||||
if ((*color)[i] == Color.Green && (*color)[j] == Color.White &&
|
||||
(*number)[j] - (*number)[i] != 1)
|
||||
foreach (immutable j; 0 .. M) {
|
||||
if (color[i] == Color.Green && color[j] == Color.White &&
|
||||
number[j] - number[i] != 1)
|
||||
return false;
|
||||
|
||||
immutable int diff = abs((*number)[i] - (*number)[j]);
|
||||
if (((*smoke)[i] == Smoke.Blend &&
|
||||
(*pet)[j] == Pet.Cat && diff != 1) ||
|
||||
((*pet)[i] == Pet.Horse &&
|
||||
(*smoke)[j] == Smoke.Dunhill && diff != 1) ||
|
||||
((*smoke)[i] == Smoke.Blend &&
|
||||
(*drink)[j] == Drink.Water && diff != 1))
|
||||
immutable diff = abs(number[i] - number[j]);
|
||||
if ((smoke[i] == Smoke.Blend && pet[j] == Pet.Cat && diff != 1) ||
|
||||
(pet[i] == Pet.Horse && smoke[j] == Smoke.Dunhill && diff != 1) ||
|
||||
(smoke[i] == Smoke.Blend && drink[j] == Drink.Water && diff != 1))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -50,32 +64,36 @@ bool isPossible(immutable Number[5]* number,
|
|||
return true;
|
||||
}
|
||||
|
||||
alias N = nullableRef; // At module level scope to be used with UFCS.
|
||||
|
||||
void main() {
|
||||
static immutable int[5][] perms = [0, 1, 2, 3, 4].permutations;
|
||||
immutable nation = [EnumMembers!Nation];
|
||||
enum size_t FM = M.factorial;
|
||||
|
||||
// Not nice casts:
|
||||
static immutable permsNumber = cast(immutable Number[5][])perms,
|
||||
permsColor = cast(immutable Color[5][])perms,
|
||||
permsDrink = cast(immutable Drink[5][])perms,
|
||||
permsSmoke = cast(immutable Smoke[5][])perms,
|
||||
permsPet = cast(immutable Pet[5][])perms;
|
||||
static immutable Number[M][FM] numberPerms = [EnumMembers!Number].permutations;
|
||||
static immutable Color[M][FM] colorPerms = [EnumMembers!Color].permutations;
|
||||
static immutable Drink[M][FM] drinkPerms = [EnumMembers!Drink].permutations;
|
||||
static immutable Smoke[M][FM] smokePerms = [EnumMembers!Smoke].permutations;
|
||||
static immutable Pet[M][FM] petPerms = [EnumMembers!Pet].permutations;
|
||||
|
||||
foreach (immutable ref number; permsNumber)
|
||||
if (isPossible(&number))
|
||||
foreach (immutable ref color; permsColor)
|
||||
if (isPossible(&number, &color))
|
||||
foreach (immutable ref drink; permsDrink)
|
||||
if (isPossible(&number, &color, &drink))
|
||||
foreach (immutable ref smoke; permsSmoke)
|
||||
if (isPossible(&number, &color, &drink, &smoke))
|
||||
foreach (immutable ref pet; permsPet)
|
||||
if (isPossible(&number,&color,&drink,&smoke,&pet)) {
|
||||
// You can reduce the compile-time computations using four casts like this:
|
||||
// static colorPerms = cast(immutable Color[M][FM])numberPerms;
|
||||
|
||||
static immutable Nation[M] nation = [EnumMembers!Nation];
|
||||
|
||||
foreach (immutable ref number; numberPerms)
|
||||
if (isPossible(number.N))
|
||||
foreach (immutable ref color; colorPerms)
|
||||
if (isPossible(number.N, color.N))
|
||||
foreach (immutable ref drink; drinkPerms)
|
||||
if (isPossible(number.N, color.N, drink.N))
|
||||
foreach (immutable ref smoke; smokePerms)
|
||||
if (isPossible(number.N, color.N, drink.N, smoke.N))
|
||||
foreach (immutable ref pet; petPerms)
|
||||
if (isPossible(number.N, color.N, drink.N, smoke.N, pet.N)) {
|
||||
writeln("Found a solution:");
|
||||
foreach (immutable x; TypeTuple!(nation, number,
|
||||
color, drink, smoke, pet))
|
||||
foreach (x; TypeTuple!(nation, number, color, drink, smoke, pet))
|
||||
writefln("%6s: %12s%12s%12s%12s%12s",
|
||||
Unqual!(typeof(x[0])).stringof,
|
||||
(Unqual!(typeof(x[0]))).stringof,
|
||||
x[0], x[1], x[2], x[3], x[4]);
|
||||
writeln;
|
||||
}
|
||||
|
|
|
|||
33
Task/Zebra-puzzle/D/zebra-puzzle-3.d
Normal file
33
Task/Zebra-puzzle/D/zebra-puzzle-3.d
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
void main() {
|
||||
import std.stdio, std.algorithm, permutations2;
|
||||
|
||||
enum E { Red, Green, Blue, White, Yellow,
|
||||
Milk, Coffee, Water, Beer, Tea,
|
||||
PallMall, Dunhill, Blend, BlueMaster, Prince,
|
||||
Dog, Cat, Zebra, Horse, Birds,
|
||||
British, Swedish, Danish, Norvegian, German }
|
||||
|
||||
enum has = (E[] a, E x, E[] b, E y) => a.countUntil(x) == b.countUntil(y);
|
||||
enum leftOf = (E[] a, E x, E[] b, E y) => a.countUntil(x) == b.countUntil(y) + 1;
|
||||
enum nextTo = (E[] a, E x, E[] b, E y) => leftOf(a, x, b, y) || leftOf(b, y, a, x);
|
||||
|
||||
with (E) foreach (houses; [Red, Blue, Green, Yellow, White].permutations)
|
||||
if (leftOf(houses, White, houses, Green))
|
||||
foreach (persons; [Norvegian, British, Swedish, German, Danish].permutations)
|
||||
if (has(persons, British, houses, Red) && persons[0] == Norvegian &&
|
||||
nextTo(persons, Norvegian, houses, Blue))
|
||||
foreach (drinks; [Tea, Coffee, Milk, Beer, Water].permutations)
|
||||
if (has(drinks, Tea, persons, Danish) &&
|
||||
has(drinks, Coffee, houses, Green) && drinks[$ / 2] == Milk)
|
||||
foreach (pets; [Dog, Birds, Cat, Horse, Zebra].permutations)
|
||||
if (has(pets, Dog, persons, Swedish))
|
||||
foreach (smokes; [PallMall, Dunhill, Blend, BlueMaster, Prince].permutations)
|
||||
if (has(smokes, PallMall, pets, Birds) &&
|
||||
has(smokes, Dunhill, houses, Yellow) &&
|
||||
nextTo(smokes, Blend, pets, Cat) &&
|
||||
nextTo(smokes, Dunhill, pets, Horse) &&
|
||||
has(smokes, BlueMaster, drinks, Beer) &&
|
||||
has(smokes, Prince, persons, German) &&
|
||||
nextTo(drinks, Water, smokes, Blend))
|
||||
writefln("%(%10s\n%)\n", [houses, persons, drinks, pets, smokes]);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue