Dinesman's multiple-dwelling problem: Difference between revisions

Content added Content deleted
(Updated D entry)
(Shorter D entry)
Line 128: Line 128:


=={{header|D}}==
=={{header|D}}==
As for flexibility: the solve function is parameterized, accepting a length argument and a variable number of function predicates.
As for flexibility: the solve code works with an arbitrary number of people and of function predicates.
<lang d>import std.stdio, std.exception, std.range, std.algorithm,
<lang d>import std.stdio, std.range, std.algorithm, std.math, std.exception;
std.math, std.traits;


struct Permutations {
struct LazyPermutations {
private immutable size_t num;
private immutable size_t num;
private uint[] seq;
private uint[] seq;
Line 181: Line 180:
}
}
}
}
}

const(uint[]) solve(T : size_t, F...)(in T len, in F predicates)
/*pure*/ nothrow {
outer:
foreach (p; Permutations(len)) {
foreach (pred; predicates)
if (!pred(p))
continue outer;
return p;
}
return null;
}
}


void main() {
void main() {
//import std.traits: EnumMembers;
enum N { Baker, Cooper, Fletcher, Miller, Smith } // names
import std.traits;
enum N { Baker, Cooper, Fletcher, Miller, Smith }


alias bool function(in uint[]) pure nothrow MutablePredicate;
alias /*immutable*/ bool function(in uint[]) pure nothrow P;
alias immutable(MutablePredicate) P;
P p1 = s => s[N.Baker] != s.length-1;
P p1 = s => s[N.Baker] != s.length-1;
P p2 = s => s[N.Cooper] != 0;
P p2 = s => s[N.Cooper] != 0;
Line 207: Line 195:
P p6 = s => abs(cast(int)(s[N.Cooper] - s[N.Fletcher])) != 1;
P p6 = s => abs(cast(int)(s[N.Cooper] - s[N.Fletcher])) != 1;


enum nFloors = EnumMembers!N.length;
enum nNames = EnumMembers!N.length;
if (auto sol = solve(nFloors, p1, p2, p3, p4, p5, p6))
immutable predicates = [p1, p2, p3, p4, p5, p6];

writeln(map!(p => [EnumMembers!N][p])(sol));
foreach (sol; LazyPermutations(nNames))
if (!canFind!(p => !p(sol))(predicates))
writeln(map!(p => [EnumMembers!N][p])(sol));
}</lang>
}</lang>
Output:
Output: