This commit is contained in:
Ingy döt Net 2013-10-27 22:24:23 +00:00
parent 6f050a029e
commit 776bba907c
3887 changed files with 59894 additions and 7280 deletions

View file

@ -0,0 +1,9 @@
{Baker, Cooper, Fletcher, Miller, Smith};
(Unequal @@ %) && (And @@ (0 < # < 6 & /@ %)) &&
Baker < 5 &&
Cooper > 1 &&
1 < Fletcher < 5 &&
Miller > Cooper &&
Abs[Smith - Fletcher] > 1 &&
Abs[Cooper - Fletcher] > 1 //
Reduce[#, %, Integers] &

View file

@ -0,0 +1 @@
Baker == 3 && Cooper == 2 && Fletcher == 4 && Miller == 5 && Smith == 1

View file

@ -0,0 +1,8 @@
p = Position[#1, #2][[1, 1]] &;
Permutations[{"Baker", "Cooper", "Fletcher", "Miller", "Smith"}, {5}];
Select[%, #[[5]] != "Baker" &];
Select[%, #[[1]] != "Cooper" &];
Select[%, #[[1]] != "Fletcher" && #[[5]] != "Fletcher" &];
Select[%, #~p~"Miller" > #~p~"Cooper" &];
Select[%, Abs[#~p~"Smith" - #~p~"Fletcher"] > 1 &];
Select[%, Abs[#~p~"Cooper" - #~p~"Fletcher"] > 1 &]

View file

@ -0,0 +1 @@
{{"Smith", "Cooper", "Baker", "Fletcher", "Miller"}}

View file

@ -18,7 +18,7 @@ Waldo:
if Baker == top then return
if Cooper == bottom then return
if Fletcher == bottom | Fletcher == top then return
if Miller <= Cooper then return
if Miller \> Cooper then return
if Smith == Fletcher-1 | Smith == Fletcher+1 then return
if Fletcher == Cooper-1 | Fletcher == Cooper+1 then return

View file

@ -0,0 +1,30 @@
def solve( problem )
lines = problem.split(".")
names = lines.first.scan( /[A-Z]\w*/ )
re_names = Regexp.union( names )
# Later on, search for these keywords (the word "not" is handled separately).
words = %w(first second third fourth fifth sixth seventh eighth nineth tenth
bottom top higher lower adjacent)
re_keywords = Regexp.union( words )
predicates = [] #build an array of lambda's
lines[1..-2].each do |line|
keywords = line.scan( re_keywords )
name1, name2 = line.scan( re_names )
keywords.each do |keyword|
l = case keyword
when "bottom" then ->(c){ c.first == name1 }
when "top" then ->(c){ c.last == name1 }
when "higher" then ->(c){ c.index( name1 ) > c.index( name2 ) }
when "lower" then ->(c){ c.index( name1 ) < c.index( name2 ) }
when "adjacent" then ->(c){ (c.index( name1 ) - c.index( name2 )).abs == 1 }
else ->(c){ c[words.index(keyword)] == name1 }
end
line =~ /\bnot\b/ ? res = ->(c){not l.call(c) } : res = l
predicates << res
end
end
names.permutation.detect{|candidate| predicates.all?{|predicate| predicate.(candidate)}}
end

View file

@ -0,0 +1,26 @@
#Direct positional words like top, bottom, first, second etc. can be combined; they refer to one name.
#The relative positional words higher, lower and adjacent can be combined; they need two names, not positions.
demo1 = "Abe Ben Charlie David. Abe not second top. not adjacent Ben Charlie.
David Abe adjacent. David adjacent Ben. Last line."
demo2 = "A B C D. A not adjacent D. not B adjacent higher C. C lower D. Last line"
problem1 = "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?"
# from the Python version:
problem2 = "Baker, Cooper, Fletcher, Miller, Guinan, and Smith
live on different floors of an apartment house that contains
only seven floors. Guinan does not live on either the top or the third or the fourth floor.
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?"
[demo1, demo2, problem1, problem2].each{|problem| puts solve( problem ) ;puts }

View file

@ -0,0 +1,10 @@
names = %i( Baker Cooper Fletcher Miller Smith )
predicates = [->(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 }]
puts names.permutation.detect{|candidate| predicates.all?{|predicate| predicate.call(candidate)}}