September 2017 Update
This commit is contained in:
parent
bba7bfd280
commit
ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions
|
|
@ -0,0 +1,39 @@
|
|||
# syntax: GAWK -f DINESMANS_MULTIPLE-DWELLING_PROBLEM.AWK
|
||||
BEGIN {
|
||||
for (Baker=1; Baker<=5; Baker++) {
|
||||
for (Cooper=1; Cooper<=5; Cooper++) {
|
||||
for (Fletcher=1; Fletcher<=5; Fletcher++) {
|
||||
for (Miller=1; Miller<=5; Miller++) {
|
||||
for (Smith=1; Smith<=5; Smith++) {
|
||||
if (rules() ~ /^1+$/) {
|
||||
printf("%d Baker\n",Baker)
|
||||
printf("%d Cooper\n",Cooper)
|
||||
printf("%d Fletcher\n",Fletcher)
|
||||
printf("%d Miller\n",Miller)
|
||||
printf("%d Smith\n",Smith)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
exit(0)
|
||||
}
|
||||
function rules( stmt1,stmt2,stmt3,stmt4,stmt5,stmt6,stmt7) {
|
||||
# The following problem statements may be changed:
|
||||
#
|
||||
# Baker, Cooper, Fletcher, Miller, and Smith live on different floors of an apartment house
|
||||
# that contains only five floors numbered 1 (ground) to 5 (top)
|
||||
stmt1 = Baker!=Cooper && Baker!=Fletcher && Baker!=Miller && Baker!=Smith &&
|
||||
Cooper!=Fletcher && Cooper!=Miller && Cooper!=Smith &&
|
||||
Fletcher!=Miller && Fletcher!=Smith &&
|
||||
Miller!=Smith
|
||||
stmt2 = Baker != 5 # Baker does not live on the top floor
|
||||
stmt3 = Cooper != 1 # Cooper does not live on the bottom floor
|
||||
stmt4 = Fletcher != 5 && Fletcher != 1 # Fletcher does not live on either the top or the bottom floor
|
||||
stmt5 = Miller > Cooper # Miller lives on a higher floor than does Cooper
|
||||
stmt6 = abs(Smith-Fletcher) != 1 # Smith does not live on a floor adjacent to Fletcher's
|
||||
stmt7 = abs(Fletcher-Cooper) != 1 # Fletcher does not live on a floor adjacent to Cooper's
|
||||
return(stmt1 stmt2 stmt3 stmt4 stmt5 stmt6 stmt7)
|
||||
}
|
||||
function abs(x) { if (x >= 0) { return x } else { return -x } }
|
||||
|
|
@ -1,81 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int verbose = 0;
|
||||
#define COND(a, b) int a(int *s) { return (b); }
|
||||
typedef int(*condition)(int *);
|
||||
|
||||
/* BEGIN problem specific setup */
|
||||
#define N_FLOORS 5
|
||||
#define TOP (N_FLOORS - 1)
|
||||
int solution[N_FLOORS] = { 0 };
|
||||
int occupied[N_FLOORS] = { 0 };
|
||||
|
||||
enum tenants {
|
||||
baker = 0,
|
||||
cooper,
|
||||
fletcher,
|
||||
miller,
|
||||
smith,
|
||||
phantom_of_the_opera,
|
||||
};
|
||||
|
||||
const char *names[] = {
|
||||
"baker",
|
||||
"cooper",
|
||||
"fletcher",
|
||||
"miller",
|
||||
"smith",
|
||||
};
|
||||
|
||||
COND(c0, s[baker] != TOP);
|
||||
COND(c1, s[cooper] != 0);
|
||||
COND(c2, s[fletcher] != 0 && s[fletcher] != TOP);
|
||||
COND(c3, s[miller] > s[cooper]);
|
||||
COND(c4, abs(s[smith] - s[fletcher]) != 1);
|
||||
COND(c5, abs(s[cooper] - s[fletcher]) != 1);
|
||||
#define N_CONDITIONS 6
|
||||
|
||||
condition cond[] = { c0, c1, c2, c3, c4, c5 };
|
||||
|
||||
/* END of problem specific setup */
|
||||
|
||||
|
||||
int solve(int person)
|
||||
{
|
||||
int i, j;
|
||||
if (person == phantom_of_the_opera) {
|
||||
/* check condition */
|
||||
for (i = 0; i < N_CONDITIONS; i++) {
|
||||
if (cond[i](solution)) continue;
|
||||
|
||||
if (verbose) {
|
||||
for (j = 0; j < N_FLOORS; j++)
|
||||
printf("%d %s\n", solution[j], names[j]);
|
||||
printf("cond %d bad\n\n", i);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("Found arrangement:\n");
|
||||
for (i = 0; i < N_FLOORS; i++)
|
||||
printf("%d %s\n", solution[i], names[i]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < N_FLOORS; i++) {
|
||||
if (occupied[i]) continue;
|
||||
solution[person] = i;
|
||||
occupied[i] = 1;
|
||||
if (solve(person + 1)) return 1;
|
||||
occupied[i] = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
verbose = 0;
|
||||
if (!solve(0)) printf("Nobody lives anywhere\n");
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
Found arrangement:
|
||||
2 baker
|
||||
1 cooper
|
||||
3 fletcher
|
||||
4 miller
|
||||
0 smith
|
||||
|
|
@ -1,64 +1,86 @@
|
|||
import java.util.*;
|
||||
|
||||
class DinesmanMultipleDwelling
|
||||
{
|
||||
private static void generatePermutations(String[] apartmentDwellers, Set<String> set, String curPermutation)
|
||||
{
|
||||
for (String s : apartmentDwellers)
|
||||
{
|
||||
if (!curPermutation.contains(s))
|
||||
{
|
||||
String nextPermutation = curPermutation + s;
|
||||
if (nextPermutation.length() == apartmentDwellers.length)
|
||||
set.add(nextPermutation);
|
||||
else
|
||||
generatePermutations(apartmentDwellers, set, nextPermutation);
|
||||
}
|
||||
class DinesmanMultipleDwelling {
|
||||
|
||||
private static void generatePermutations(String[] apartmentDwellers, Set<String> set, String curPermutation) {
|
||||
for (String s : apartmentDwellers) {
|
||||
if (!curPermutation.contains(s)) {
|
||||
String nextPermutation = curPermutation + s;
|
||||
if (nextPermutation.length() == apartmentDwellers.length) {
|
||||
set.add(nextPermutation);
|
||||
} else {
|
||||
generatePermutations(apartmentDwellers, set, nextPermutation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
private static boolean topFloor(String permutation, String person)
|
||||
{ return permutation.endsWith(person); }
|
||||
|
||||
private static boolean bottomFloor(String permutation, String person)
|
||||
{ return permutation.startsWith(person); }
|
||||
|
||||
public static boolean livesAbove(String permutation, String upperPerson, String lowerPerson)
|
||||
{ return permutation.indexOf(upperPerson) > permutation.indexOf(lowerPerson); }
|
||||
|
||||
public static boolean adjacent(String permutation, String person1, String person2)
|
||||
{ return (Math.abs(permutation.indexOf(person1) - permutation.indexOf(person2)) == 1); }
|
||||
|
||||
private static boolean isPossible(String s)
|
||||
{
|
||||
// Conditions here
|
||||
if (topFloor(s, "B"))
|
||||
return false;
|
||||
if (bottomFloor(s, "C"))
|
||||
return false;
|
||||
if (topFloor(s, "F") || bottomFloor(s, "F"))
|
||||
return false;
|
||||
if (!livesAbove(s, "M", "C"))
|
||||
return false;
|
||||
if (adjacent(s, "S", "F"))
|
||||
return false;
|
||||
if (adjacent(s, "F", "C"))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
Set<String> set = new HashSet<String>();
|
||||
generatePermutations(new String[] { "B", "C", "F", "M", "S" }, set, "");
|
||||
for (Iterator<String> iterator = set.iterator(); iterator.hasNext(); )
|
||||
{
|
||||
String permutation = iterator.next();
|
||||
if (!isPossible(permutation))
|
||||
iterator.remove();
|
||||
private static boolean topFloor(String permutation, String person) { //Checks to see if the person is on the top floor
|
||||
return permutation.endsWith(person);
|
||||
}
|
||||
|
||||
private static boolean bottomFloor(String permutation, String person) {//Checks to see if the person is on the bottom floor
|
||||
return permutation.startsWith(person);
|
||||
}
|
||||
|
||||
public static boolean livesAbove(String permutation, String upperPerson, String lowerPerson) {//Checks to see if the person lives above the other person
|
||||
return permutation.indexOf(upperPerson) > permutation.indexOf(lowerPerson);
|
||||
}
|
||||
|
||||
public static boolean adjacent(String permutation, String person1, String person2) { //checks to see if person1 is adjacent to person2
|
||||
return (Math.abs(permutation.indexOf(person1) - permutation.indexOf(person2)) == 1);
|
||||
}
|
||||
|
||||
private static boolean isPossible(String s) {
|
||||
/*
|
||||
What this does should be obvious...proper explaination can be given if needed
|
||||
Conditions here Switching any of these to ! or reverse will change what is given as a result
|
||||
|
||||
example
|
||||
if(topFloor(s, "B"){
|
||||
}
|
||||
to
|
||||
if(!topFloor(s, "B"){
|
||||
}
|
||||
or the opposite
|
||||
if(!topFloor(s, "B"){
|
||||
}
|
||||
to
|
||||
if(topFloor(s, "B"){
|
||||
}
|
||||
*/
|
||||
if (topFloor(s, "B")) {//B is on Top Floor
|
||||
return false;
|
||||
}
|
||||
if (bottomFloor(s, "C")) {//C is on Bottom Floor
|
||||
return false;
|
||||
}
|
||||
if (topFloor(s, "F") || bottomFloor(s, "F")) {// F is on top or bottom floor
|
||||
return false;
|
||||
}
|
||||
if (!livesAbove(s, "M", "C")) {// M does not live above C
|
||||
return false;
|
||||
}
|
||||
if (adjacent(s, "S", "F")) { //S lives adjacent to F
|
||||
return false;
|
||||
}
|
||||
return !adjacent(s, "F", "C"); //F does not live adjacent to C
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Set<String> set = new HashSet<String>();
|
||||
generatePermutations(new String[]{"B", "C", "F", "M", "S"}, set, ""); //Generates Permutations
|
||||
for (Iterator<String> iterator = set.iterator(); iterator.hasNext();) {//Loops through iterator
|
||||
String permutation = iterator.next();
|
||||
if (!isPossible(permutation)) {//checks to see if permutation is false if so it removes it
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
for (String s : set) {
|
||||
System.out.println("Possible arrangement: " + s);
|
||||
/*
|
||||
Prints out possible arranagement...changes depending on what you change in the "isPossible method"
|
||||
*/
|
||||
}
|
||||
}
|
||||
for (String s : set)
|
||||
System.out.println("Possible arrangement: " + s);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,50 @@
|
|||
// version 1.1.3
|
||||
|
||||
typealias Predicate = (List<String>) -> Boolean
|
||||
|
||||
fun <T> permute(input: List<T>): List<List<T>> {
|
||||
if (input.size == 1) return listOf(input)
|
||||
val perms = mutableListOf<List<T>>()
|
||||
val toInsert = input[0]
|
||||
for (perm in permute(input.drop(1))) {
|
||||
for (i in 0..perm.size) {
|
||||
val newPerm = perm.toMutableList()
|
||||
newPerm.add(i, toInsert)
|
||||
perms.add(newPerm)
|
||||
}
|
||||
}
|
||||
return perms
|
||||
}
|
||||
|
||||
/* looks for for all possible solutions, not just the first */
|
||||
fun dinesman(occupants: List<String>, predicates: List<Predicate>) =
|
||||
permute(occupants).filter { perm -> predicates.all { pred -> pred(perm) } }
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val occupants = listOf("Baker", "Cooper", "Fletcher", "Miller", "Smith")
|
||||
|
||||
val predicates = listOf<Predicate>(
|
||||
{ it.last() != "Baker" },
|
||||
{ it.first() != "Cooper" },
|
||||
{ it.last() != "Fletcher" && it.first() != "Fletcher" },
|
||||
{ it.indexOf("Miller") > it.indexOf("Cooper") },
|
||||
{ Math.abs(it.indexOf("Smith") - it.indexOf("Fletcher")) > 1 },
|
||||
{ Math.abs(it.indexOf("Fletcher") - it.indexOf("Cooper")) > 1 }
|
||||
)
|
||||
|
||||
val solutions = dinesman(occupants, predicates)
|
||||
val size = solutions.size
|
||||
if (size == 0) {
|
||||
println("No solutions found")
|
||||
}
|
||||
else {
|
||||
val plural = if (size == 1) "" else "s"
|
||||
println("$size solution$plural found, namely:\n")
|
||||
for (solution in solutions) {
|
||||
for ((i, name) in solution.withIndex()) {
|
||||
println("Floor ${i + 1} -> $name")
|
||||
}
|
||||
println()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
enum Baker, Cooper, Fletcher, Miller, Smith
|
||||
constant names={"Baker","Cooper","Fletcher","Miller","Smith"}
|
||||
|
||||
procedure test(sequence flats)
|
||||
if flats[Baker]!=5
|
||||
and flats[Cooper]!=1
|
||||
and not find(flats[Fletcher],{1,5})
|
||||
and flats[Miller]>flats[Cooper]
|
||||
and abs(flats[Smith]-flats[Fletcher])!=1
|
||||
and abs(flats[Fletcher]-flats[Cooper])!=1 then
|
||||
for i=1 to 5 do
|
||||
?{names[i],flats[i]}
|
||||
end for
|
||||
end if
|
||||
end procedure
|
||||
|
||||
for i=1 to factorial(5) do
|
||||
test(permute(i,tagset(5)))
|
||||
end for
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
sequence names = {"Baker","Cooper","Fletcher","Miller","Smith"},
|
||||
rules = {{"!=","Baker",length(names)},
|
||||
{"!=","Cooper",1},
|
||||
{"!=","Fletcher",1},
|
||||
{"!=","Fletcher",length(names)},
|
||||
{">","Miller","Cooper"},
|
||||
-- {"!=",{"abs","Smith","Fletcher"},1},
|
||||
{"nadj","Smith","Fletcher"},
|
||||
-- {"!=",{"abs","Fletcher","Cooper"},1},
|
||||
{"nadj","Fletcher","Cooper"}}
|
||||
|
||||
function eval(sequence rule, sequence flats)
|
||||
{string operand, object op1, object op2} = rule
|
||||
if string(op1) then
|
||||
op1 = flats[find(op1,names)]
|
||||
-- elsif sequence(op1) then
|
||||
-- op1 = eval(op1,flats)
|
||||
end if
|
||||
if string(op2) then
|
||||
op2 = flats[find(op2,names)]
|
||||
-- elsif sequence(op2) then
|
||||
-- op2 = eval(op2,flats)
|
||||
end if
|
||||
switch operand do
|
||||
case "!=": return op1!=op2
|
||||
case ">": return op1>op2
|
||||
-- case "abs": return abs(op1-op2)
|
||||
case "nadj": return abs(op1-op2)!=1
|
||||
end switch
|
||||
return 9/0
|
||||
end function
|
||||
|
||||
procedure test(sequence flats)
|
||||
for i=1 to length(rules) do
|
||||
if not eval(rules[i],flats) then return end if
|
||||
end for
|
||||
for i=1 to length(names) do
|
||||
?{names[i],flats[i]}
|
||||
end for
|
||||
end procedure
|
||||
|
||||
for i=1 to factorial(length(names)) do
|
||||
test(permute(i,tagset(length(names))))
|
||||
end for
|
||||
|
|
@ -1,18 +1,18 @@
|
|||
func dinesman(problem) {
|
||||
var lines = problem.split('.');
|
||||
var names = lines.first.scan(/\b[A-Z]\w*/);
|
||||
var re_names = Regex(names.join('|'));
|
||||
|
||||
var lines = problem.split('.')
|
||||
var names = lines.first.scan(/\b[A-Z]\w*/)
|
||||
var re_names = Regex(names.join('|'))
|
||||
|
||||
# Later on, search for these keywords (the word "not" is handled separately).
|
||||
var words = %w(first second third fourth fifth sixth seventh eighth ninth tenth
|
||||
bottom top higher lower adjacent);
|
||||
var re_keywords = Regex(words.join('|'));
|
||||
|
||||
bottom top higher lower adjacent)
|
||||
var re_keywords = Regex(words.join('|'))
|
||||
|
||||
# Build an array of lambda's
|
||||
var predicates = lines.ft(1, lines.end-1).map{ |line|
|
||||
var keywords = line.scan(re_keywords);
|
||||
var (name1, name2) = line.scan(re_names)...;
|
||||
|
||||
var keywords = line.scan(re_keywords)
|
||||
var (name1, name2) = line.scan(re_names)...
|
||||
|
||||
keywords.map{ |keyword|
|
||||
var l = do {
|
||||
given(keyword) {
|
||||
|
|
@ -24,11 +24,11 @@ func dinesman(problem) {
|
|||
default { ->(c) { c[words.index(keyword)] == name1 } }
|
||||
}
|
||||
}
|
||||
line ~~ /\bnot\b/ ? func(c) { l(c) -> not } : l; # handle "not"
|
||||
line ~~ /\bnot\b/ ? func(c) { l(c) -> not } : l; # handle "not"
|
||||
}
|
||||
}.flatten;
|
||||
|
||||
names.permutations { |candidate|
|
||||
predicates.all { |predicate| predicate(candidate) } && return candidate;
|
||||
}.flat
|
||||
|
||||
names.permutations { |*candidate|
|
||||
predicates.all { |predicate| predicate(candidate) } && return candidate
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,4 +19,4 @@ floor than does Cooper. Smith does not live on a floor
|
|||
adjacent to Fletcher's. Fletcher does not live on a floor
|
||||
adjacent to Cooper's. Where does everyone live?"
|
||||
|
||||
[demo1, demo2, problem1, problem2].each{|problem| say dinesman(problem).join("\n"); say '' };
|
||||
[demo1, demo2, problem1, problem2].each{|problem| say dinesman(problem).join("\n"); say '' }
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
var names = %w(Baker Cooper Fletcher Miller Smith)
|
||||
|
||||
|
||||
var predicates = [
|
||||
->(c){ :Baker != c.last },
|
||||
->(c){ :Cooper != c.first },
|
||||
->(c){ (:Fletcher != c.first) && (:Fletcher != c.last) },
|
||||
->(c){ :Baker != c.last },
|
||||
->(c){ :Cooper != c.first },
|
||||
->(c){ (:Fletcher != c.first) && (:Fletcher != c.last) },
|
||||
->(c){ c.index(:Miller) > c.index(:Cooper) },
|
||||
->(c){ (c.index(:Smith) - c.index(:Fletcher)).abs != 1 },
|
||||
->(c){ (c.index(:Cooper) - c.index(:Fletcher)).abs != 1 },
|
||||
->(c){ (c.index(:Smith) - c.index(:Fletcher)).abs != 1 },
|
||||
->(c){ (c.index(:Cooper) - c.index(:Fletcher)).abs != 1 },
|
||||
]
|
||||
|
||||
names.permutations { |candidate|
|
||||
|
||||
names.permutations { |*candidate|
|
||||
if (predicates.all {|predicate| predicate(candidate) }) {
|
||||
say candidate.join("\n")
|
||||
break
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
var Baker, Cooper, Fletcher, Miller, Smith; // value == floor
|
||||
const bottom=1,top=5; // floors: 1..5
|
||||
// All live on different floors, enforced by using permutations of floors
|
||||
//fcn c0{ (Baker!=Cooper!=Fletcher) and (Fletcher!=Miller!=Smith) }
|
||||
fcn c1{ Baker!=top }
|
||||
fcn c2{ Cooper!=bottom }
|
||||
fcn c3{ bottom!=Fletcher!=top }
|
||||
fcn c4{ Miller>Cooper }
|
||||
fcn c5{ (Fletcher - Smith).abs() !=1 }
|
||||
fcn c6{ (Fletcher - Cooper).abs()!=1 }
|
||||
|
||||
filters:=T(c1,c2,c3,c4,c5,c6);
|
||||
dudes:=T("Baker","Cooper","Fletcher","Miller","Smith"); // for reflection
|
||||
foreach combo in (Utils.Helpers.permuteW([bottom..top].walk())){ // lazy
|
||||
dudes.zip(combo).apply2(fcn(nameValue){ setVar(nameValue.xplode()) });
|
||||
if(not filters.runNFilter(False)){ // all constraints are True
|
||||
vars.println(); // use reflection to print solution
|
||||
break;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue