September 2017 Update

This commit is contained in:
Ingy döt Net 2017-09-23 10:01:46 +02:00
parent bba7bfd280
commit ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions

View file

@ -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 } }

View file

@ -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;
}

View file

@ -1,6 +0,0 @@
Found arrangement:
2 baker
1 cooper
3 fletcher
4 miller
0 smith

View file

@ -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);
}
}

View file

@ -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()
}
}
}

View file

@ -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

View file

@ -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

View file

@ -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
}
}

View file

@ -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 '' }

View file

@ -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

View file

@ -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;
}
}