Just another update
This commit is contained in:
parent
a25938f123
commit
00a190b0a6
6591 changed files with 94363 additions and 23227 deletions
|
|
@ -1,8 +1,18 @@
|
|||
The task is to '''solve Dinesman's multiple dwelling [http://www-mitpress.mit.edu/sicp/full-text/book/book-Z-H-28.html#%_sec_4.3.2 problem] but in a way that most naturally follows the problem statement given below'''. Solutions are allowed (but not required) to parse and interpret the problem text, but should remain flexible and should state what changes to the problem text are allowed. Flexibility and ease of expression are valued.
|
||||
{{omit from|GUISS}}
|
||||
The task is to '''solve Dinesman's multiple dwelling [http://www-mitpress.mit.edu/sicp/full-text/book/book-Z-H-28.html#%_sec_4.3.2 problem] but in a way that most naturally follows the problem statement given below'''.
|
||||
|
||||
Solutions are allowed (but not required) to parse and interpret the problem text, but should remain flexible and should state what changes to the problem text are allowed. Flexibility and ease of expression are valued.
|
||||
|
||||
Examples may be be split into "setup", "problem statement", and "output" sections where the ease and naturalness of stating the problem and getting an answer, as well as the ease and flexibility of modifying the problem are the primary concerns.
|
||||
|
||||
Example output should be shown here, as well as any comments on the examples flexibility.
|
||||
|
||||
;The problem:
|
||||
:''Baker, Cooper, Fletcher, Miller, and Smith live on different floors of an apartment house that contains only five floors. Baker does not live on the top floor. Cooper does not live on the bottom floor. Fletcher does not live on either the top or the bottom floor. Miller lives on a higher 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?''
|
||||
:Baker, Cooper, Fletcher, Miller, and Smith live on different floors of an apartment house that contains only five floors.
|
||||
:Baker does not live on the top floor.
|
||||
:Cooper does not live on the bottom floor.
|
||||
:Fletcher does not live on either the top or the bottom floor.
|
||||
:Miller lives on a higher 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?''
|
||||
|
|
|
|||
2
Task/Dinesmans-multiple-dwelling-problem/00META.yaml
Normal file
2
Task/Dinesmans-multiple-dwelling-problem/00META.yaml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
note: Dinesman's multiple-dwelling problem
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
#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 +1,6 @@
|
|||
import std.stdio, std.math, std.algorithm, permutations2;
|
||||
|
||||
void main() {
|
||||
import std.stdio, std.math, std.algorithm, permutations2;
|
||||
|
||||
["Baker", "Cooper", "Fletcher", "Miller", "Smith"]
|
||||
.permutations
|
||||
.filter!(s =>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,39 @@
|
|||
sub parse_and_solve ($text) {
|
||||
my %ids;
|
||||
my $expr = (grammar {
|
||||
rule TOP { <fact>+ { make join ' && ', $<fact>>>.made } }
|
||||
|
||||
rule fact { <name> (not)? <position>
|
||||
{ make sprintf $<position>.made.fmt($0 ?? "!(%s)" !! "%s"),
|
||||
$<name>.made }
|
||||
}
|
||||
rule position {
|
||||
|| on bottom { make "\@f[%s] == 1" }
|
||||
|| on top { make "\@f[%s] == +\@f" }
|
||||
|| lower than <name> { make "\@f[%s] < \@f[{$<name>.made}]" }
|
||||
|| higher than <name> { make "\@f[%s] > \@f[{$<name>.made}]" }
|
||||
|| directly below <name> { make "\@f[%s] == \@f[{$<name>.made}] - 1" }
|
||||
|| directly above <name> { make "\@f[%s] == \@f[{$<name>.made}] + 1" }
|
||||
|| adjacent to <name> { make "\@f[%s] == \@f[{$<name>.made}] + (-1|1)" }
|
||||
|| on <ordinal> { make "\@f[%s] == {$<ordinal>.made}" }
|
||||
|| { note "Failed to parse line " ~ +$/.prematch.comb(/^^/); exit 1; }
|
||||
}
|
||||
|
||||
token name { :i <[a..z]>+ { make %ids{~$/} //= (state $)++ } }
|
||||
token ordinal { [1st | 2nd | 3rd | \d+th] { make +$/.match(/(\d+)/)[0] } }
|
||||
}).parse($text).made;
|
||||
|
||||
EVAL 'for [1..%ids.elems].permutations -> @f {
|
||||
say %ids.kv.map({ "$^a=@f[$^b]" }) if (' ~ $expr ~ ');
|
||||
}'
|
||||
}
|
||||
|
||||
parse_and_solve Q:to/END/;
|
||||
Baker not on top
|
||||
Cooper not on bottom
|
||||
Fletcher not on top
|
||||
Fletcher not on bottom
|
||||
Miller higher than Cooper
|
||||
Smith not adjacent to Fletcher
|
||||
Fletcher not adjacent to Cooper
|
||||
END
|
||||
|
|
@ -1,20 +1,5 @@
|
|||
sub next_perm ( @a is copy ) {
|
||||
my $j = @a.end - 1;
|
||||
return Nil if --$j < 0 while [>] @a[ $j, $j+1 ];
|
||||
|
||||
my $aj = @a[$j];
|
||||
my $k = @a.end;
|
||||
$k-- while [>] $aj, @a[$k];
|
||||
@a[ $j, $k ] .= reverse;
|
||||
|
||||
my $r = @a.end;
|
||||
my $s = $j + 1;
|
||||
@a[ $r--, $s++ ] .= reverse while $r > $s;
|
||||
return @a;
|
||||
}
|
||||
|
||||
# Contains only five floors. 5! = 120 permutations.
|
||||
for [1..5], &next_perm ...^ !* -> [ $b, $c, $f, $m, $s ] {
|
||||
for [1..5].permutations -> $b, $c, $f, $m, $s {
|
||||
say "Baker=$b Cooper=$c Fletcher=$f Miller=$m Smith=$s"
|
||||
if $b != 5 # Baker !live on top floor.
|
||||
and $c != 1 # Cooper !live on bottom floor.
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
use strict;
|
||||
use warnings;
|
||||
use feature qw(state say);
|
||||
use List::Util 1.33 qw(pairmap);
|
||||
use Algorithm::Permute qw(permute);
|
||||
|
||||
our %predicates = (
|
||||
# | object | sprintf format for Perl expression |
|
||||
# --------------------+-----------+------------------------------------+
|
||||
'on bottom' => [ '' , '$f[%s] == 1' ],
|
||||
'on top' => [ '' , '$f[%s] == @f' ],
|
||||
'lower than' => [ 'person' , '$f[%s] < $f[%s]' ],
|
||||
'higher than' => [ 'person' , '$f[%s] > $f[%s]' ],
|
||||
'directly below' => [ 'person' , '$f[%s] == $f[%s] - 1' ],
|
||||
'directly above' => [ 'person' , '$f[%s] == $f[%s] + 1' ],
|
||||
'adjacent to' => [ 'person' , 'abs($f[%s] - $f[%s]) == 1' ],
|
||||
'on' => [ 'ordinal' , '$f[%s] == \'%s\'' ],
|
||||
);
|
||||
|
||||
our %nouns = (
|
||||
'person' => qr/[a-z]+/i,
|
||||
'ordinal' => qr/1st | 2nd | 3rd | \d+th/x,
|
||||
);
|
||||
|
||||
sub parse_and_solve {
|
||||
my @facts = @_;
|
||||
|
||||
state $parser = qr/^(?<subj>$nouns{person}) (?<not>not )?(?|@{[
|
||||
join '|', pairmap {
|
||||
"(?<pred>$a)" .
|
||||
($b->[0] ? " (?<obj>$nouns{$b->[0]})" : '')
|
||||
} %predicates
|
||||
]})$/;
|
||||
|
||||
my (@expressions, %ids, $i);
|
||||
my $id = sub { defined $_[0] ? $ids{$_[0]} //= $i++ : () };
|
||||
|
||||
foreach (@facts) {
|
||||
/$parser/ or die "Cannot parse '$_'\n";
|
||||
|
||||
my $pred = $predicates{$+{pred}};
|
||||
my $expr = '(' . sprintf($pred->[1], $id->($+{subj}),
|
||||
$pred->[0] eq 'person' ? $id->($+{obj}) : $+{obj}). ')';
|
||||
$expr = '!' . $expr if $+{not};
|
||||
|
||||
push @expressions, $expr;
|
||||
}
|
||||
|
||||
my @f = 1..$i;
|
||||
eval 'no warnings "numeric";
|
||||
permute {
|
||||
say join(", ", pairmap { "$f[$b] $a" } %ids)
|
||||
if ('.join(' && ', @expressions).');
|
||||
} @f;';
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
parse_and_solve(<DATA>);
|
||||
|
||||
__DATA__
|
||||
Baker not on top
|
||||
Cooper not on bottom
|
||||
Fletcher not on top
|
||||
Fletcher not on bottom
|
||||
Miller higher than Cooper
|
||||
Smith not adjacent to Fletcher
|
||||
Fletcher not adjacent to Cooper
|
||||
|
|
@ -1,31 +1,27 @@
|
|||
object Dinesman extends App {
|
||||
import scala.math.abs
|
||||
|
||||
val tenants = List("Baker", "Cooper", "Fletcher", "Miller", "Smith")
|
||||
val floors = (1 to tenants.size).toList
|
||||
object Dinesman3 extends App {
|
||||
val tenants = List("Baker", "Cooper2", "Fletcher4", "Miller", "Smith")
|
||||
val (groundFloor, topFloor) = (1, tenants.size)
|
||||
|
||||
// define the predicates
|
||||
import scala.math.abs
|
||||
val predicates =
|
||||
List((perm: Map[String, Int]) => !(perm("Baker")==floors.size)
|
||||
,(perm: Map[String, Int]) => !(perm("Cooper")==1)
|
||||
,(perm: Map[String, Int]) => !(perm("Fletcher")==1 || perm("Fletcher")==floors.size)
|
||||
,(perm: Map[String, Int]) => !(perm("Miller")<=perm("Cooper"))
|
||||
,(perm: Map[String, Int]) => !(abs(perm("Smith")-perm("Fletcher"))==1)
|
||||
,(perm: Map[String, Int]) => !(abs(perm("Fletcher")-perm("Cooper"))==1)
|
||||
)
|
||||
|
||||
val p: Seq[(String, Int)] => Boolean = perm => !predicates.map(_(perm.toMap)).contains(false)
|
||||
|
||||
tenants.permutations.map(_ zip floors).toList
|
||||
.map(perm=>Pair(perm,p(perm))).filter(_._2==true).map(p=>p._1.toList)
|
||||
match {
|
||||
case Nil => println("no solution")
|
||||
case xss => { println("solutions: "+xss.size)
|
||||
xss.foreach{l=>
|
||||
println("possible solution:")
|
||||
l.foreach(p=>println(" "+p._1+ " lives on floor number "+p._2))
|
||||
}
|
||||
}
|
||||
}
|
||||
/** Rules with related tenants and restrictions*/
|
||||
val exclusions =
|
||||
List((suggestedFloor0: Map[String, Int]) => suggestedFloor0("Baker") != topFloor,
|
||||
(suggestedFloor1: Map[String, Int]) => suggestedFloor1("Cooper2") != groundFloor,
|
||||
(suggestedFloor2: Map[String, Int]) => !List(groundFloor, topFloor).contains(suggestedFloor2("Fletcher4")),
|
||||
(suggestedFloor3: Map[String, Int]) => suggestedFloor3("Miller") > suggestedFloor3("Cooper2"),
|
||||
(suggestedFloor4: Map[String, Int]) => abs(suggestedFloor4("Smith") - suggestedFloor4("Fletcher4")) != 1,
|
||||
(suggestedFloor5: Map[String, Int]) => abs(suggestedFloor5("Fletcher4") - suggestedFloor5("Cooper2")) != 1)
|
||||
|
||||
tenants.permutations.map(_ zip (groundFloor to topFloor)).
|
||||
filter(p => exclusions.forall(_(p.toMap))).toList match {
|
||||
case Nil => println("No solution")
|
||||
case xss => {
|
||||
println(s"Solutions: ${xss.size}")
|
||||
xss.foreach { l =>
|
||||
println("possible solution:")
|
||||
l.foreach(p => println(f"${p._1}%11s lives on floor number ${p._2}"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,31 @@
|
|||
...
|
||||
val tenants = List("Baker", "Cooper", "Fletcher", "Miller", "Smith", "Rollo")
|
||||
...
|
||||
val predicates =
|
||||
List((perm: Map[String, Int]) => !(perm("Baker")==floors.size)
|
||||
...
|
||||
,(perm: Map[String, Int]) => !(perm("Rollo")==floors.size || perm("Rollo")==3 || perm("Rollo")==4)
|
||||
,(perm: Map[String, Int]) => !(perm("Rollo")>perm("Smith"))
|
||||
,(perm: Map[String, Int]) => !(perm("Rollo")<perm("Fletcher"))
|
||||
)
|
||||
...
|
||||
import scala.math.abs
|
||||
|
||||
object Dinesman3 extends App {
|
||||
val tenants = List("Baker", "Cooper2", "Fletcher4", "Miller", "Rollo5", "Smith")
|
||||
val (groundFloor, topFloor) = (1, tenants.size)
|
||||
|
||||
/** Rules with related tenants and restrictions*/
|
||||
val exclusions =
|
||||
List((suggestedFloor0: Map[String, Int]) => suggestedFloor0("Baker") != topFloor,
|
||||
(suggestedFloor1: Map[String, Int]) => suggestedFloor1("Cooper2") != groundFloor,
|
||||
(suggestedFloor2: Map[String, Int]) => !List(groundFloor, topFloor).contains(suggestedFloor2("Fletcher4")),
|
||||
(suggestedFloor3: Map[String, Int]) => suggestedFloor3("Miller") > suggestedFloor3("Cooper2"),
|
||||
(suggestedFloor4: Map[String, Int]) => abs(suggestedFloor4("Smith") - suggestedFloor4("Fletcher4")) != 1,
|
||||
(suggestedFloor5: Map[String, Int]) => abs(suggestedFloor5("Fletcher4") - suggestedFloor5("Cooper2")) != 1,
|
||||
|
||||
(suggestedFloor6: Map[String, Int]) => !List(3, 4, topFloor).contains(suggestedFloor6("Rollo5")),
|
||||
(suggestedFloor7: Map[String, Int]) => suggestedFloor7("Rollo5") < suggestedFloor7("Smith"),
|
||||
(suggestedFloor8: Map[String, Int]) => suggestedFloor8("Rollo5") > suggestedFloor8("Fletcher4"))
|
||||
|
||||
tenants.permutations.map(_ zip (groundFloor to topFloor)).
|
||||
filter(p => exclusions.forall(_(p.toMap))).toList match {
|
||||
case Nil => println("No solution")
|
||||
case xss => {
|
||||
println(s"Solutions: ${xss.size}")
|
||||
xss.foreach { l =>
|
||||
println("possible solution:")
|
||||
l.foreach(p => println(f"${p._1}%11s lives on floor number ${p._2}"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
import scala.math.abs
|
||||
|
||||
object Dinesman2 extends App {
|
||||
val groundFloor = 1
|
||||
|
||||
abstract class Rule(val person: String) { val exclusion: Map[String, Int] => Boolean }
|
||||
|
||||
/** Rules with related tenants and restrictions*/
|
||||
def rulesDef(topFloor: Int) = List(
|
||||
new Rule("Baker") { val exclusion = (_: Map[String, Int])(person) != topFloor },
|
||||
new Rule("Cooper2") { val exclusion = (_: Map[String, Int])(person) != groundFloor },
|
||||
new Rule("Fletcher4") {
|
||||
val exclusion = (suggestedFloor2: Map[String, Int]) => !List(groundFloor, topFloor).contains(suggestedFloor2(person))
|
||||
}, new Rule("Miller") {
|
||||
val exclusion = (suggestedFloor3: Map[String, Int]) => suggestedFloor3(person) > suggestedFloor3("Cooper2")
|
||||
}, new Rule("Smith") {
|
||||
val exclusion = (suggestedFloor4: Map[String, Int]) => abs(suggestedFloor4(person) - suggestedFloor4("Fletcher4")) != 1
|
||||
}, new Rule("Fletcher4") {
|
||||
val exclusion = (suggestedFloor5: Map[String, Int]) => abs(suggestedFloor5(person) - suggestedFloor5("Cooper2")) != 1
|
||||
})
|
||||
|
||||
def extensionDef(topFloor: Int) = List(new Rule("Rollo5") {
|
||||
val exclusion = (suggestedFloor6: Map[String, Int]) => !List(3, 4, topFloor).contains((suggestedFloor6: Map[String, Int])(person))
|
||||
}, new Rule("Rollo5") {
|
||||
val exclusion = (suggestedFloor7: Map[String, Int]) => suggestedFloor7(person) < suggestedFloor7("Smith")
|
||||
}, new Rule("Rollo5") {
|
||||
val exclusion = (suggestedFloor8: Map[String, Int]) => suggestedFloor8(person) > suggestedFloor8("Fletcher4")
|
||||
})
|
||||
|
||||
def allRulesDef(topFloor: Int) = rulesDef(topFloor) ++ extensionDef(topFloor)
|
||||
|
||||
val tenants = allRulesDef(0).map(_.person).distinct // Pilot balloon to get # of tenants
|
||||
val topFloor = tenants.size
|
||||
val exclusions = allRulesDef(topFloor).map(_.exclusion)
|
||||
|
||||
tenants.permutations.map(_ zip (groundFloor to topFloor)).
|
||||
filter(p => exclusions.forall(_(p.toMap))).toList match {
|
||||
case Nil => println("No solution")
|
||||
case xss => {
|
||||
println(s"Solutions: ${xss.size}")
|
||||
xss.foreach { l =>
|
||||
println("possible solution:")
|
||||
l.foreach(p => println(f"${p._1}%11s lives on floor number ${p._2}"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue